3 use bytes
::{Bytes, BytesMut}
;
5 pub trait IndexFile
: Send
{
6 fn index_count(&self) -> usize;
7 fn index_digest(&self, pos
: usize) -> Option
<&[u8; 32]>;
10 /// Encode digest list from an `IndexFile` into a binary stream
12 /// The reader simply returns a birary stream of 32 byte digest values.
13 pub struct DigestListEncoder
{
14 index
: Box
<dyn IndexFile
>,
19 impl DigestListEncoder
{
21 pub fn new(index
: Box
<dyn IndexFile
>) -> Self {
22 let count
= index
.index_count();
23 Self { index, pos: 0, count }
27 impl std
::io
::Read
for DigestListEncoder
{
29 fn read(&mut self, buf
: &mut [u8]) -> Result
<usize, std
::io
::Error
> {
30 if buf
.len() < 32 { panic!("read buffer too small"); }
31 if self.pos
< self.count
{
34 let digest
= self.index
.index_digest(self.pos
).unwrap();
35 unsafe { std::ptr::copy_nonoverlapping(digest.as_ptr(), buf.as_mut_ptr().add(written), 32); }
38 if self.pos
>= self.count { break; }
39 if (written
+ 32) >= buf
.len() { break; }
48 /// Decodes a Stream<Item=Bytes> into Stream<Item=<[u8;32]>
50 /// The reader simply returns a birary stream of 32 byte digest values.
52 pub struct DigestListDecoder
<S
> {
57 impl <S
> DigestListDecoder
<S
> {
59 pub fn new(input
: S
) -> Self {
60 Self { input, buffer: BytesMut::new() }
64 impl <S
> Stream
for DigestListDecoder
<S
>
65 where S
: Stream
<Item
=Bytes
>,
66 S
::Error
: Into
<Error
>,
71 fn poll(&mut self) -> Result
<Async
<Option
<Self::Item
>>, Self::Error
> {
74 if self.buffer
.len() >= 32 {
76 let left
= self.buffer
.split_to(32);
78 let mut digest
: [u8; 32] = unsafe { std::mem::uninitialized() }
;
79 unsafe { std::ptr::copy_nonoverlapping(left.as_ptr(), digest.as_mut_ptr(), 32); }
81 return Ok(Async
::Ready(Some(digest
)));
84 match self.input
.poll() {
86 return Err(err
.into());
88 Ok(Async
::NotReady
) => {
89 return Ok(Async
::NotReady
);
91 Ok(Async
::Ready(None
)) => {
92 let rest
= self.buffer
.len();
93 if rest
== 0 { return Ok(Async::Ready(None)); }
94 return Err(format_err
!("got small digest ({} != 32).", rest
));
96 Ok(Async
::Ready(Some(data
))) => {
97 self.buffer
.extend_from_slice(&data
);