diff options
Diffstat (limited to '')
-rw-r--r-- | src/stable/clientbuf.cpp | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/src/stable/clientbuf.cpp b/src/stable/clientbuf.cpp new file mode 100644 index 0000000..493e577 --- /dev/null +++ b/src/stable/clientbuf.cpp | |||
@@ -0,0 +1,465 @@ | |||
1 | #include "bu/clientbuf.h" | ||
2 | |||
3 | #include "bu/mutexlocker.h" | ||
4 | |||
5 | Bu::ClientBuf::ClientBuf() : | ||
6 | accClientRaw( *this ), | ||
7 | accServer( *this ), | ||
8 | accClientFiltered( &accClient ), | ||
9 | accClient( *this ) | ||
10 | { | ||
11 | } | ||
12 | |||
13 | Bu::ClientBuf::~ClientBuf() | ||
14 | { | ||
15 | } | ||
16 | |||
17 | Bu::ClientBuf::ClientAccess &Bu::ClientBuf::client() | ||
18 | { | ||
19 | return accClient; | ||
20 | } | ||
21 | |||
22 | Bu::ClientBuf::ServerAccess &Bu::ClientBuf::server() | ||
23 | { | ||
24 | return accServer; | ||
25 | } | ||
26 | |||
27 | ///////// | ||
28 | // ClientAccessRaw | ||
29 | /// | ||
30 | |||
31 | Bu::ClientBuf::ClientAccessRaw::ClientAccessRaw( Bu::ClientBuf &rBuf ) : | ||
32 | rBuf( rBuf ) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | Bu::ClientBuf::ClientAccessRaw::~ClientAccessRaw() | ||
37 | { | ||
38 | } | ||
39 | |||
40 | void Bu::ClientBuf::ClientAccessRaw::close() | ||
41 | { | ||
42 | // Roughly meaningless | ||
43 | } | ||
44 | |||
45 | Bu::size Bu::ClientBuf::ClientAccessRaw::read( void *pBuf, size iBytes ) | ||
46 | { | ||
47 | Bu::MutexLocker l( rBuf.mInput ); | ||
48 | return rBuf.qbInput.read( pBuf, iBytes ); | ||
49 | } | ||
50 | |||
51 | Bu::size Bu::ClientBuf::ClientAccessRaw::write( const void *pBuf, size iBytes ) | ||
52 | { | ||
53 | Bu::MutexLocker l( rBuf.mOutput ); | ||
54 | return rBuf.qbOutput.write( pBuf, iBytes ); | ||
55 | } | ||
56 | |||
57 | Bu::size Bu::ClientBuf::ClientAccessRaw::tell() | ||
58 | { | ||
59 | Bu::MutexLocker l( rBuf.mInput ); | ||
60 | return rBuf.qbInput.tell(); | ||
61 | } | ||
62 | |||
63 | void Bu::ClientBuf::ClientAccessRaw::seek( Bu::size offset ) | ||
64 | { | ||
65 | Bu::MutexLocker l( rBuf.mInput ); | ||
66 | rBuf.qbInput.seek( offset ); | ||
67 | } | ||
68 | |||
69 | void Bu::ClientBuf::ClientAccessRaw::setPos( Bu::size ) | ||
70 | { | ||
71 | } | ||
72 | |||
73 | void Bu::ClientBuf::ClientAccessRaw::setPosEnd( Bu::size ) | ||
74 | { | ||
75 | } | ||
76 | |||
77 | bool Bu::ClientBuf::ClientAccessRaw::isEos() | ||
78 | { | ||
79 | Bu::MutexLocker l( rBuf.mInput ); | ||
80 | return rBuf.qbInput.isEos(); | ||
81 | } | ||
82 | |||
83 | bool Bu::ClientBuf::ClientAccessRaw::isOpen() | ||
84 | { | ||
85 | Bu::MutexLocker l( rBuf.mInput ); | ||
86 | return rBuf.qbInput.isOpen(); | ||
87 | } | ||
88 | |||
89 | void Bu::ClientBuf::ClientAccessRaw::flush() | ||
90 | { | ||
91 | Bu::MutexLocker l( rBuf.mOutput ); | ||
92 | return rBuf.qbOutput.flush(); | ||
93 | } | ||
94 | |||
95 | bool Bu::ClientBuf::ClientAccessRaw::canRead() | ||
96 | { | ||
97 | Bu::MutexLocker l( rBuf.mInput ); | ||
98 | return rBuf.qbInput.canRead(); | ||
99 | } | ||
100 | |||
101 | bool Bu::ClientBuf::ClientAccessRaw::canWrite() | ||
102 | { | ||
103 | Bu::MutexLocker l( rBuf.mOutput ); | ||
104 | return rBuf.qbOutput.canWrite(); | ||
105 | } | ||
106 | |||
107 | bool Bu::ClientBuf::ClientAccessRaw::isReadable() | ||
108 | { | ||
109 | Bu::MutexLocker l( rBuf.mInput ); | ||
110 | return rBuf.qbInput.isReadable(); | ||
111 | } | ||
112 | |||
113 | bool Bu::ClientBuf::ClientAccessRaw::isWritable() | ||
114 | { | ||
115 | Bu::MutexLocker l( rBuf.mOutput ); | ||
116 | return rBuf.qbOutput.isWritable(); | ||
117 | } | ||
118 | |||
119 | bool Bu::ClientBuf::ClientAccessRaw::isSeekable() | ||
120 | { | ||
121 | Bu::MutexLocker l( rBuf.mInput ); | ||
122 | return rBuf.qbInput.isSeekable(); | ||
123 | } | ||
124 | |||
125 | bool Bu::ClientBuf::ClientAccessRaw::isBlocking() | ||
126 | { | ||
127 | return false; | ||
128 | } | ||
129 | |||
130 | void Bu::ClientBuf::ClientAccessRaw::setBlocking( bool ) | ||
131 | { | ||
132 | } | ||
133 | |||
134 | void Bu::ClientBuf::ClientAccessRaw::setSize( Bu::size ) | ||
135 | { | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | Bu::size Bu::ClientBuf::ClientAccessRaw::getSize() const | ||
140 | { | ||
141 | Bu::MutexLocker l( rBuf.mInput ); | ||
142 | return rBuf.qbInput.getSize(); | ||
143 | } | ||
144 | |||
145 | Bu::size Bu::ClientBuf::ClientAccessRaw::getBlockSize() const | ||
146 | { | ||
147 | Bu::MutexLocker l( rBuf.mInput ); | ||
148 | return rBuf.qbInput.getBlockSize(); | ||
149 | } | ||
150 | |||
151 | Bu::String Bu::ClientBuf::ClientAccessRaw::getLocation() const | ||
152 | { | ||
153 | return "ClientBuf"; | ||
154 | } | ||
155 | |||
156 | ///////// | ||
157 | // ClientAccess | ||
158 | /// | ||
159 | |||
160 | Bu::ClientBuf::ClientAccess::ClientAccess( Bu::ClientBuf &rBuf ) : | ||
161 | rBuf( rBuf ) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | Bu::ClientBuf::ClientAccess::~ClientAccess() | ||
166 | { | ||
167 | } | ||
168 | |||
169 | void Bu::ClientBuf::ClientAccess::close() | ||
170 | { | ||
171 | // Roughly meaningless | ||
172 | } | ||
173 | |||
174 | Bu::size Bu::ClientBuf::ClientAccess::read( void *pBufRaw, size iBytes ) | ||
175 | { | ||
176 | char *pBuf = (char *)pBufRaw; | ||
177 | Bu::MutexLocker l( mAccess ); | ||
178 | // Read from QueueBuf first | ||
179 | Bu::size ps = qbPeek.read( pBuf, iBytes ); | ||
180 | iBytes -= ps; | ||
181 | pBuf += ps; | ||
182 | // Request space left? Try the client | ||
183 | if( iBytes > 0 ) | ||
184 | { | ||
185 | ps += rBuf.accClientFiltered.read( pBuf, iBytes ); | ||
186 | } | ||
187 | return ps; | ||
188 | } | ||
189 | |||
190 | Bu::size Bu::ClientBuf::ClientAccess::peek( void *pData, int iBytes, | ||
191 | int iOffset ) | ||
192 | { | ||
193 | Bu::MutexLocker l( mAccess ); | ||
194 | // Do we have enough data in the peek buffer to handle this? | ||
195 | if( qbPeek.getSize() < iBytes+iOffset ) | ||
196 | { | ||
197 | // Nope, make an attempt to fill it in. | ||
198 | int nDiff = iBytes-qbPeek.getSize(); | ||
199 | // We have to make our own buffer, since iBytes+nOffeset could be bigger | ||
200 | // than pData. | ||
201 | char *pTmp = new char[nDiff]; | ||
202 | Bu::size ps = rBuf.accClientFiltered.read( pTmp, nDiff ); | ||
203 | if( ps > 0 ) | ||
204 | { | ||
205 | // Add the data read to the peek buffer. | ||
206 | qbPeek.write( pTmp, ps ); | ||
207 | } | ||
208 | delete[] pTmp; | ||
209 | } | ||
210 | |||
211 | return qbPeek.peek( pData, iBytes, iOffset ); | ||
212 | } | ||
213 | |||
214 | Bu::size Bu::ClientBuf::ClientAccess::write( const void *pBuf, size iBytes ) | ||
215 | { | ||
216 | Bu::MutexLocker l( mAccess ); | ||
217 | return rBuf.accClientFiltered.write( pBuf, iBytes ); | ||
218 | } | ||
219 | |||
220 | Bu::size Bu::ClientBuf::ClientAccess::tell() | ||
221 | { | ||
222 | Bu::MutexLocker l( mAccess ); | ||
223 | return rBuf.accClientFiltered.tell() + qbPeek.getSize(); | ||
224 | } | ||
225 | |||
226 | void Bu::ClientBuf::ClientAccess::seek( Bu::size offset ) | ||
227 | { | ||
228 | Bu::MutexLocker l( mAccess ); | ||
229 | // For this type of stream seek is basically a destructive skip. It's like | ||
230 | // reading the data but with no output buffer. Let's remove data from the | ||
231 | // peek buffer first. | ||
232 | if( qbPeek.getSize() > 0 ) | ||
233 | { | ||
234 | Bu::size amount = Bu::buMax( qbPeek.getSize(), offset ); | ||
235 | qbPeek.seek( amount ); | ||
236 | offset -= amount; | ||
237 | } | ||
238 | |||
239 | // If there's offset left, then apply it to the underlying stream | ||
240 | if( offset > 0 ) | ||
241 | { | ||
242 | rBuf.accClientFiltered.seek( offset ); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | void Bu::ClientBuf::ClientAccess::setPos( Bu::size ) | ||
247 | { | ||
248 | } | ||
249 | |||
250 | void Bu::ClientBuf::ClientAccess::setPosEnd( Bu::size ) | ||
251 | { | ||
252 | } | ||
253 | |||
254 | bool Bu::ClientBuf::ClientAccess::isEos() | ||
255 | { | ||
256 | Bu::MutexLocker l( mAccess ); | ||
257 | return rBuf.accClientFiltered.isEos(); | ||
258 | } | ||
259 | |||
260 | bool Bu::ClientBuf::ClientAccess::isOpen() | ||
261 | { | ||
262 | Bu::MutexLocker l( mAccess ); | ||
263 | return rBuf.accClientFiltered.isOpen(); | ||
264 | } | ||
265 | |||
266 | void Bu::ClientBuf::ClientAccess::flush() | ||
267 | { | ||
268 | Bu::MutexLocker l( mAccess ); | ||
269 | return rBuf.accClientFiltered.flush(); | ||
270 | } | ||
271 | |||
272 | bool Bu::ClientBuf::ClientAccess::canRead() | ||
273 | { | ||
274 | Bu::MutexLocker l( mAccess ); | ||
275 | return rBuf.accClientFiltered.canRead(); | ||
276 | } | ||
277 | |||
278 | bool Bu::ClientBuf::ClientAccess::canWrite() | ||
279 | { | ||
280 | Bu::MutexLocker l( mAccess ); | ||
281 | return rBuf.accClientFiltered.canWrite(); | ||
282 | } | ||
283 | |||
284 | bool Bu::ClientBuf::ClientAccess::isReadable() | ||
285 | { | ||
286 | Bu::MutexLocker l( mAccess ); | ||
287 | return rBuf.accClientFiltered.isReadable(); | ||
288 | } | ||
289 | |||
290 | bool Bu::ClientBuf::ClientAccess::isWritable() | ||
291 | { | ||
292 | Bu::MutexLocker l( mAccess ); | ||
293 | return rBuf.accClientFiltered.isWritable(); | ||
294 | } | ||
295 | |||
296 | bool Bu::ClientBuf::ClientAccess::isSeekable() | ||
297 | { | ||
298 | Bu::MutexLocker l( mAccess ); | ||
299 | return rBuf.accClientFiltered.isSeekable(); | ||
300 | } | ||
301 | |||
302 | bool Bu::ClientBuf::ClientAccess::isBlocking() | ||
303 | { | ||
304 | return false; | ||
305 | } | ||
306 | |||
307 | void Bu::ClientBuf::ClientAccess::setBlocking( bool ) | ||
308 | { | ||
309 | } | ||
310 | |||
311 | void Bu::ClientBuf::ClientAccess::setSize( Bu::size ) | ||
312 | { | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | Bu::size Bu::ClientBuf::ClientAccess::getSize() const | ||
317 | { | ||
318 | Bu::MutexLocker l( mAccess ); | ||
319 | return rBuf.accClientFiltered.getSize() + qbPeek.getSize(); | ||
320 | } | ||
321 | |||
322 | Bu::size Bu::ClientBuf::ClientAccess::getBlockSize() const | ||
323 | { | ||
324 | Bu::MutexLocker l( mAccess ); | ||
325 | return rBuf.accClientFiltered.getBlockSize(); | ||
326 | } | ||
327 | |||
328 | Bu::String Bu::ClientBuf::ClientAccess::getLocation() const | ||
329 | { | ||
330 | return "ClientBuf"; | ||
331 | } | ||
332 | |||
333 | ///////// | ||
334 | // ServerAccess | ||
335 | /// | ||
336 | |||
337 | Bu::ClientBuf::ServerAccess::ServerAccess( Bu::ClientBuf &rBuf ) : | ||
338 | rBuf( rBuf ) | ||
339 | { | ||
340 | } | ||
341 | |||
342 | Bu::ClientBuf::ServerAccess::~ServerAccess() | ||
343 | { | ||
344 | } | ||
345 | |||
346 | void Bu::ClientBuf::ServerAccess::close() | ||
347 | { | ||
348 | } | ||
349 | |||
350 | Bu::size Bu::ClientBuf::ServerAccess::read( void *pBuf, size iBytes ) | ||
351 | { | ||
352 | Bu::MutexLocker l( rBuf.mOutput ); | ||
353 | return rBuf.qbOutput.read( pBuf, iBytes ); | ||
354 | } | ||
355 | |||
356 | Bu::size Bu::ClientBuf::ServerAccess::peek( void *pData, int iBytes, int iOffset ) | ||
357 | { | ||
358 | Bu::MutexLocker l( rBuf.mOutput ); | ||
359 | return rBuf.qbOutput.peek( pData, iBytes, iOffset ); | ||
360 | } | ||
361 | |||
362 | Bu::size Bu::ClientBuf::ServerAccess::write( const void *pBuf, size iBytes ) | ||
363 | { | ||
364 | Bu::MutexLocker l( rBuf.mInput ); | ||
365 | return rBuf.qbInput.write( pBuf, iBytes ); | ||
366 | } | ||
367 | |||
368 | Bu::size Bu::ClientBuf::ServerAccess::tell() | ||
369 | { | ||
370 | Bu::MutexLocker l( rBuf.mOutput ); | ||
371 | return rBuf.qbOutput.tell(); | ||
372 | } | ||
373 | |||
374 | void Bu::ClientBuf::ServerAccess::seek( Bu::size offset ) | ||
375 | { | ||
376 | Bu::MutexLocker l( rBuf.mOutput ); | ||
377 | rBuf.qbOutput.seek( offset ); | ||
378 | } | ||
379 | |||
380 | void Bu::ClientBuf::ServerAccess::setPos( Bu::size ) | ||
381 | { | ||
382 | } | ||
383 | |||
384 | void Bu::ClientBuf::ServerAccess::setPosEnd( Bu::size ) | ||
385 | { | ||
386 | } | ||
387 | |||
388 | bool Bu::ClientBuf::ServerAccess::isEos() | ||
389 | { | ||
390 | Bu::MutexLocker l( rBuf.mOutput ); | ||
391 | return rBuf.qbOutput.isEos(); | ||
392 | } | ||
393 | |||
394 | bool Bu::ClientBuf::ServerAccess::isOpen() | ||
395 | { | ||
396 | Bu::MutexLocker l( rBuf.mOutput ); | ||
397 | return rBuf.qbOutput.isOpen(); | ||
398 | } | ||
399 | |||
400 | void Bu::ClientBuf::ServerAccess::flush() | ||
401 | { | ||
402 | Bu::MutexLocker l( rBuf.mInput ); | ||
403 | return rBuf.qbInput.flush(); | ||
404 | } | ||
405 | |||
406 | bool Bu::ClientBuf::ServerAccess::canRead() | ||
407 | { | ||
408 | Bu::MutexLocker l( rBuf.mOutput ); | ||
409 | return rBuf.qbOutput.canRead(); | ||
410 | } | ||
411 | |||
412 | bool Bu::ClientBuf::ServerAccess::canWrite() | ||
413 | { | ||
414 | Bu::MutexLocker l( rBuf.mInput ); | ||
415 | return rBuf.qbInput.canWrite(); | ||
416 | } | ||
417 | |||
418 | bool Bu::ClientBuf::ServerAccess::isReadable() | ||
419 | { | ||
420 | Bu::MutexLocker l( rBuf.mOutput ); | ||
421 | return rBuf.qbOutput.isReadable(); | ||
422 | } | ||
423 | |||
424 | bool Bu::ClientBuf::ServerAccess::isWritable() | ||
425 | { | ||
426 | Bu::MutexLocker l( rBuf.mInput ); | ||
427 | return rBuf.qbInput.isWritable(); | ||
428 | } | ||
429 | |||
430 | bool Bu::ClientBuf::ServerAccess::isSeekable() | ||
431 | { | ||
432 | Bu::MutexLocker l( rBuf.mOutput ); | ||
433 | return rBuf.qbOutput.isSeekable(); | ||
434 | } | ||
435 | |||
436 | bool Bu::ClientBuf::ServerAccess::isBlocking() | ||
437 | { | ||
438 | return false; | ||
439 | } | ||
440 | |||
441 | void Bu::ClientBuf::ServerAccess::setBlocking( bool ) | ||
442 | { | ||
443 | } | ||
444 | |||
445 | void Bu::ClientBuf::ServerAccess::setSize( Bu::size ) | ||
446 | { | ||
447 | return; | ||
448 | } | ||
449 | |||
450 | Bu::size Bu::ClientBuf::ServerAccess::getSize() const | ||
451 | { | ||
452 | Bu::MutexLocker l( rBuf.mOutput ); | ||
453 | return rBuf.qbOutput.getSize(); | ||
454 | } | ||
455 | |||
456 | Bu::size Bu::ClientBuf::ServerAccess::getBlockSize() const | ||
457 | { | ||
458 | Bu::MutexLocker l( rBuf.mOutput ); | ||
459 | return rBuf.qbOutput.getBlockSize(); | ||
460 | } | ||
461 | |||
462 | Bu::String Bu::ClientBuf::ServerAccess::getLocation() const | ||
463 | { | ||
464 | return "ClientBuf"; | ||
465 | } | ||