]>
code.octet-stream.net Git - m17rt/blob - m17app/src/util/out_buffer.rs
1 //! Buffer between `read()` calls
4 io
::{self, ErrorKind
, Read
},
5 sync
::{mpsc
::Receiver
, Arc
, Mutex
},
14 /// Buffer binary chunks from an MPSC receiver, feeding arbitrary chunks to `read()` calls.
16 /// Can be cloned, but should only be read from once at a time.
18 pub struct OutBuffer
{
19 rx
: Arc
<Mutex
<Receiver
<Arc
<[u8]>>>>,
20 partial_out
: Arc
<Mutex
<Option
<PartialOut
>>>,
24 pub fn new(rx
: Receiver
<Arc
<[u8]>>) -> Self {
26 rx
: Arc
::new(Mutex
::new(rx
)),
27 partial_out
: Arc
::new(Mutex
::new(None
)),
32 impl Read
for OutBuffer
{
33 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
35 let mut partial_out
= self.partial_out
.lock().unwrap
();
36 if let Some(partial
) = partial_out
.as_mut() {
37 let remaining
= partial
.output
.len() - partial
.idx
;
38 let to_write
= remaining
.min(buf
.len());
40 .copy_from_slice(&partial
.output
[partial
.idx
..(partial
.idx
+ to_write
)]);
41 if to_write
== remaining
{
44 partial
.idx
+= to_write
;
50 let rx
= self.rx
.lock().unwrap
();
52 .map_err(|s
| io
::Error
::new(ErrorKind
::Other
, format
!("{:?}", s
)))?
54 let to_write
= output
.len().min(buf
.len());
55 buf
[0..to_write
].copy_from_slice(&output
[0..to_write
]);
56 if to_write
!= output
.len() {
57 *self.partial_out
.lock().unwrap
() = Some(PartialOut
{