equal
deleted
inserted
replaced
6 #include <cstdlib> |
6 #include <cstdlib> |
7 |
7 |
8 /* |
8 /* |
9 * NetworkBufferBase |
9 * NetworkBufferBase |
10 */ |
10 */ |
11 NetworkBufferBase::NetworkBufferBase (NetworkSocket &socket, size_t size_hint) : |
11 NetworkBufferBase::NetworkBufferBase (NetworkSocket *socket, size_t size_hint) : |
12 socket(socket), buf(0), size(0), offset(0) { |
12 socket(socket), buf(0), size(0), offset(0) { |
13 |
13 |
14 // allocate initial buffer |
14 // allocate initial buffer |
15 if ((buf = (char *) malloc(size_hint)) == NULL) |
15 if ((buf = (char *) malloc(size_hint)) == NULL) |
16 throw NetworkBufferError("malloc failed"); |
16 throw NetworkBufferError("malloc failed"); |
57 } |
57 } |
58 |
58 |
59 /* |
59 /* |
60 * NetworkBufferInput |
60 * NetworkBufferInput |
61 */ |
61 */ |
62 NetworkBufferInput::NetworkBufferInput (NetworkSocket &socket, size_t size_hint) : |
62 NetworkBufferInput::NetworkBufferInput (NetworkSocket *socket, size_t size_hint) : |
63 NetworkBufferBase(socket, size_hint) |
63 NetworkBufferBase(socket, size_hint) |
64 { |
64 { |
65 |
65 |
66 } |
66 } |
67 |
67 |
68 bool NetworkBufferInput::try_read (size_t item_size) { |
68 bool NetworkBufferInput::try_read (size_t item_size) { |
69 int ret; |
69 size_t ret, to_read = item_size; |
70 size_t to_read = item_size; |
|
71 |
70 |
72 // keept reads at at least NETWORK_BUFFER_CHUNK_SIZE bytes |
71 // keept reads at at least NETWORK_BUFFER_CHUNK_SIZE bytes |
73 if (to_read < NETWORK_BUFFER_CHUNK_SIZE) |
72 if (to_read < NETWORK_BUFFER_CHUNK_SIZE) |
74 to_read = NETWORK_BUFFER_CHUNK_SIZE; |
73 to_read = NETWORK_BUFFER_CHUNK_SIZE; |
75 |
74 |
76 // resize buffer if needed |
75 // resize buffer if needed |
77 resize(to_read); |
76 resize(to_read); |
78 |
77 |
79 // read once |
78 // read once |
80 try { |
79 ret = socket->recv(buf + offset, to_read); |
81 ret = socket.recv(buf + offset, to_read); |
|
82 |
80 |
83 } catch (CL_Error &e) { |
81 // nothing left? |
84 if (errno == EAGAIN) |
|
85 return false; |
|
86 |
|
87 else |
|
88 throw NetworkSocketOSError(socket, "recv"); |
|
89 } |
|
90 |
|
91 // handle EOF |
|
92 if (ret == 0) |
82 if (ret == 0) |
93 throw NetworkSocketEOFError(socket, "recv"); |
83 return false; |
94 |
|
95 assert(ret >= 0); |
|
96 |
84 |
97 // update offset |
85 // update offset |
98 offset += ret; |
86 offset += ret; |
99 |
87 |
100 // did we get enough? |
88 // did we get enough? |
127 } |
115 } |
128 |
116 |
129 /* |
117 /* |
130 * NetworkBufferOutput |
118 * NetworkBufferOutput |
131 */ |
119 */ |
132 NetworkBufferOutput::NetworkBufferOutput (NetworkSocket &socket, size_t size_hint) : |
120 NetworkBufferOutput::NetworkBufferOutput (NetworkSocket *socket, size_t size_hint) : |
133 NetworkBufferBase(socket, size_hint) |
121 NetworkBufferBase(socket, size_hint) |
134 { |
122 { |
135 |
123 |
136 } |
124 } |
137 |
125 |
138 |
126 |
139 void NetworkBufferOutput::push_write (char *buf_ptr, size_t buf_size) { |
127 void NetworkBufferOutput::push_write (char *buf_ptr, size_t buf_size) { |
140 int ret; |
128 size_t ret; |
141 |
129 |
142 // try and short-circuit writes unless we have already buffered data |
130 // try and short-circuit writes unless we have already buffered data |
143 if (offset == 0) { |
131 if (offset == 0) { |
144 try { |
132 // attempt to send something |
145 // attempt to send something |
133 ret = socket->send(buf_ptr, buf_size); |
146 ret = socket.send(buf_ptr, buf_size); |
|
147 |
134 |
148 } catch (CL_Error &e) { |
|
149 // ignore EAGAIN, detect this by setting ret to -1 |
|
150 if (errno != EAGAIN) |
|
151 throw NetworkSocketOSError(socket, "send"); |
|
152 |
|
153 ret = -1; |
|
154 } |
|
155 |
|
156 // if we managed to send something, adjust buf/size and buffer |
135 // if we managed to send something, adjust buf/size and buffer |
157 if (ret > 0) { |
136 if (ret > 0) { |
158 // sanity-check |
137 // sanity-check |
159 assert(buf_size >= (unsigned int) ret); |
138 assert(buf_size >= (unsigned int) ret); |
160 |
139 |
173 // copy into our internal buffer |
152 // copy into our internal buffer |
174 memcpy(buf + offset, buf_ptr, buf_size); |
153 memcpy(buf + offset, buf_ptr, buf_size); |
175 } |
154 } |
176 |
155 |
177 void NetworkBufferOutput::flush_write (void) { |
156 void NetworkBufferOutput::flush_write (void) { |
178 int ret; |
157 size_t ret; |
179 |
158 |
180 // ignore if we don't have any data buffered |
159 // ignore if we don't have any data buffered |
181 if (offset == 0) |
160 if (offset == 0) |
182 return; |
161 return; |
183 |
162 |
184 // attempt to write as much as possible |
163 // attempt to write as much as possible |
185 try { |
164 ret = socket->send(buf, offset); |
186 ret = socket.send(buf, offset); |
|
187 |
165 |
188 } catch (CL_Error &e) { |
166 // busy? |
189 // ignore EAGAIN and just return |
167 if (ret == 0) |
190 if (errno == EAGAIN) |
168 return; |
191 return; |
|
192 |
|
193 else |
|
194 throw NetworkSocketOSError(socket, "send"); |
|
195 } |
|
196 |
169 |
197 // trim the buffer |
170 // trim the buffer |
198 trim(ret); |
171 trim(ret); |
199 } |
172 } |
200 |
173 |