11use std:: {
22 fmt:: Display ,
3- io:: { self , Read , Write } ,
3+ io:: { self , ErrorKind , Read , Write } ,
44 mem,
55} ;
66
@@ -23,16 +23,17 @@ type Buffer = BitArray<[u8; 1], Msb0>;
2323/// # fn main() -> Result<(), io::Error> {
2424/// // pack
2525/// let mut writer = Io::new(Vec::<u8>::new());
26- /// writer.pack_as::<u8, NBits<7>>(123, ())?
26+ /// writer
27+ /// .pack_as::<u8, NBits<7>>(123, ())?
2728/// .pack(true, ())?;
28- /// let buf = writer.into_inner ().unwrap();
29+ /// let buf = writer.stop_and_flush ().unwrap();
2930///
3031/// // unpack
3132/// let mut reader = Io::new(buf.as_slice());
3233/// let value1 = reader.unpack_as::<u8, NBits<7>>(())?;
3334/// let value2 = reader.unpack::<bool>(())?;
34- ///
35- /// # assert!(reader.buffered() .is_empty());
35+ /// let buf = reader.checked_discard().unwrap();
36+ /// assert!(buf .is_empty());
3637/// # assert_eq!(value1, 123);
3738/// # assert_eq!(value2, true);
3839/// # Ok(())
@@ -109,21 +110,42 @@ impl<T> Io<T> {
109110 }
110111}
111112
113+ impl < R > Io < R >
114+ where
115+ R : Read ,
116+ {
117+ /// Safely discards the underlying reader: if any buffered and not-yet-consumed
118+ /// bits left, then checks that it was a stop-bit followed by zeros. Otherwise,
119+ /// returns an error.
120+ ///
121+ /// Returns total number of buffered bits discarded.
122+ pub fn checked_discard ( self ) -> Result < R , io:: Error > {
123+ // check if some not yet comsumed bits left
124+ if let Some ( ( stop, rest) ) = self . buffered ( ) . split_first ( ) {
125+ // check that it's only a stop-bit followed by zeros
126+ if !* stop || rest. any ( ) {
127+ return Err ( io:: Error :: new ( ErrorKind :: InvalidData , "not all bits read" ) ) ;
128+ }
129+ }
130+ Ok ( self . into_inner_unchecked ( ) )
131+ }
132+ }
133+
112134impl < W > Io < W >
113135where
114136 W : Write ,
115137{
116- pub fn fill_up_buffer_and_flush (
117- & mut self ,
118- fill_bit : bool ,
119- ) -> Result < usize , <Self as BitWriter >:: Error > {
120- Ok ( if !self . buffered ( ) . is_empty ( ) {
138+ /// Finalizes the writer: if any buffered and not-yet-flushed bits left,
139+ /// then writes a stop-bit, fills up the rest by zeros and flushes the buffer.
140+ ///
141+ /// Returns total number of additional bits written.
142+ pub fn stop_and_flush ( mut self ) -> Result < W , io:: Error > {
143+ if !self . buffered ( ) . is_empty ( ) {
144+ self . write_bit ( true ) ?; // put stop-bit
121145 let n = self . buffer_capacity_left ( ) ;
122- self . repeat_bit ( n, fill_bit) ?;
123- n
124- } else {
125- 0
126- } )
146+ self . repeat_bit ( n, false ) ?; // fill the rest with zeros
147+ }
148+ Ok ( self . into_inner_unchecked ( ) )
127149 }
128150}
129151
@@ -268,6 +290,26 @@ where
268290 }
269291 Ok ( ( ) )
270292 }
293+
294+ fn repeat_bit ( & mut self , mut n : usize , bit : bool ) -> Result < ( ) , Self :: Error > {
295+ while n > 0 && !self . buffered ( ) . is_empty ( ) {
296+ self . write_bit ( bit) ?;
297+ n -= 1 ;
298+ }
299+
300+ n -= io:: copy (
301+ & mut io:: repeat ( if bit { !0 } else { 0 } ) . take ( ( n / bits_of :: < u8 > ( ) ) as u64 ) ,
302+ & mut self . io ,
303+ ) ? as usize
304+ * bits_of :: < u8 > ( ) ;
305+
306+ while n > 0 {
307+ self . write_bit ( bit) ?;
308+ n -= 1 ;
309+ }
310+
311+ Ok ( ( ) )
312+ }
271313}
272314
273315impl Error for io:: Error {
0 commit comments