1- use crate :: Error ;
1+ use std:: io:: Read ;
2+
3+ use crate :: error:: Error ;
4+
5+ use super :: read_u8;
26
37#[ derive( Debug , Copy , Clone , PartialEq ) ]
4- pub enum BooleanRun < ' a > {
8+ #[ allow( clippy:: large_enum_variant) ]
9+ pub enum BooleanRun {
510 Run ( u8 , u16 ) ,
6- Literals ( & ' a [ u8 ] ) ,
11+ Literals ( [ u8 ; 255 ] ) ,
712}
813
9- pub struct BooleanRleRunIter < ' a > {
10- stream : & ' a [ u8 ] ,
14+ pub struct BooleanRleRunIter < ' a , R : Read > {
15+ reader : & ' a mut R ,
1116}
1217
13- impl < ' a > BooleanRleRunIter < ' a > {
14- pub fn new ( stream : & ' a [ u8 ] ) -> Self {
15- Self { stream }
18+ impl < ' a , R : Read > BooleanRleRunIter < ' a , R > {
19+ pub fn new ( reader : & ' a mut R ) -> Self {
20+ Self { reader }
1621 }
1722}
1823
19- impl < ' a > Iterator for BooleanRleRunIter < ' a > {
20- type Item = Result < BooleanRun < ' a > , Error > ;
24+ fn read_literals < R : Read > ( reader : & mut R , header : i8 ) -> Result < [ u8 ; 255 ] , Error > {
25+ let length = ( -header) as usize ;
26+
27+ let mut literals = [ 0u8 ; 255 ] ;
28+
29+ reader
30+ . take ( length as u64 )
31+ . read_exact ( & mut literals[ ..length] ) ?;
32+
33+ Ok ( literals)
34+ }
35+
36+ impl < ' a , R : Read > Iterator for BooleanRleRunIter < ' a , R > {
37+ type Item = Result < BooleanRun , Error > ;
2138
2239 #[ inline]
2340 fn next ( & mut self ) -> Option < Self :: Item > {
24- let header = * self . stream . first ( ) ?;
25- self . stream = & self . stream [ 1 ..] ;
26- let header = i8:: from_le_bytes ( [ header] ) ;
41+ let header = read_u8 ( self . reader ) ;
42+ let header = match header {
43+ Ok ( header) => header as i8 ,
44+ Err ( e) => return Some ( Err ( e. into ( ) ) ) ,
45+ } ;
2746 if header < 0 {
28- let length = ( -header) as usize ;
29- if length > self . stream . len ( ) {
30- return Some ( Err ( Error :: RleLiteralTooLarge ) ) ;
31- }
32- let ( literals, remaining) = self . stream . split_at ( length) ;
33- self . stream = remaining;
34- Some ( Ok ( BooleanRun :: Literals ( literals) ) )
47+ Some ( read_literals ( self . reader , header) . map ( BooleanRun :: Literals ) )
3548 } else {
3649 let length = header as u16 + 3 ;
37- let value = self . stream [ 0 ] ;
38- self . stream = & self . stream [ 1 ..] ;
50+ // this is not ok - it may require more than one byte
51+ let value = read_u8 ( self . reader ) ;
52+ let value = match value {
53+ Ok ( value) => value,
54+ Err ( e) => return Some ( Err ( e. into ( ) ) ) ,
55+ } ;
3956 Some ( Ok ( BooleanRun :: Run ( value, length) ) )
4057 }
4158 }
4259}
4360
44- pub struct BooleanIter < ' a > {
45- iter : BooleanRleRunIter < ' a > ,
46- current : Option < BooleanRun < ' a > > ,
61+ pub struct BooleanIter < ' a , R : Read > {
62+ iter : BooleanRleRunIter < ' a , R > ,
63+ current : Option < BooleanRun > ,
4764 position : u8 ,
65+ byte_position : usize ,
4866 remaining : usize ,
4967}
5068
51- impl < ' a > BooleanIter < ' a > {
52- pub fn new ( stream : & ' a [ u8 ] , length : usize ) -> Self {
69+ impl < ' a , R : Read > BooleanIter < ' a , R > {
70+ pub fn new ( reader : & ' a mut R , length : usize ) -> Self {
5371 Self {
54- iter : BooleanRleRunIter :: new ( stream ) ,
72+ iter : BooleanRleRunIter :: new ( reader ) ,
5573 current : None ,
5674 position : 0 ,
75+ byte_position : 0 ,
5776 remaining : length,
5877 }
5978 }
6079}
6180
62- impl < ' a > Iterator for BooleanIter < ' a > {
81+ impl < ' a , R : Read > Iterator for BooleanIter < ' a , R > {
6382 type Item = Result < bool , Error > ;
6483
6584 #[ inline]
@@ -89,7 +108,7 @@ impl<'a> Iterator for BooleanIter<'a> {
89108 }
90109 BooleanRun :: Literals ( bytes) => {
91110 let mask = 128u8 >> self . position ;
92- let result = bytes[ 0 ] & mask == mask;
111+ let result = bytes[ self . byte_position ] & mask == mask;
93112 self . position += 1 ;
94113 if self . remaining == 0 {
95114 self . current = None ;
@@ -100,8 +119,9 @@ impl<'a> Iterator for BooleanIter<'a> {
100119 if self . position == 8 {
101120 if bytes. len ( ) == 1 {
102121 self . current = None ;
122+ self . byte_position = 0 ;
103123 } else {
104- self . current = Some ( BooleanRun :: Literals ( & bytes [ 1 .. ] ) ) ;
124+ self . byte_position += 1 ;
105125 }
106126 self . position = 0 ;
107127 }
@@ -128,3 +148,54 @@ impl<'a> Iterator for BooleanIter<'a> {
128148 ( self . remaining , Some ( self . remaining ) )
129149 }
130150}
151+
152+ #[ cfg( test) ]
153+ mod test {
154+ use super :: * ;
155+
156+ #[ test]
157+ fn basic ( ) {
158+ let data = [ 0x61u8 , 0x00 ] ;
159+
160+ let data = & mut data. as_ref ( ) ;
161+
162+ let iter = BooleanIter :: new ( data, 100 )
163+ . collect :: < Result < Vec < _ > , Error > > ( )
164+ . unwrap ( ) ;
165+ assert_eq ! ( iter, vec![ false ; 100 ] )
166+ }
167+
168+ #[ test]
169+ fn literals ( ) {
170+ let data = [ 0xfeu8 , 0b01000100 , 0b01000101 ] ;
171+
172+ let data = & mut data. as_ref ( ) ;
173+
174+ let iter = BooleanIter :: new ( data, 16 )
175+ . collect :: < Result < Vec < _ > , Error > > ( )
176+ . unwrap ( ) ;
177+ assert_eq ! (
178+ iter,
179+ vec![
180+ false , true , false , false , false , true , false , false , // 0b01000100
181+ false , true , false , false , false , true , false , true , // 0b01000101
182+ ]
183+ )
184+ }
185+
186+ #[ test]
187+ fn another ( ) {
188+ // "For example, the byte sequence [0xff, 0x80] would be one true followed by seven false values."
189+ let data = [ 0xff , 0x80 ] ;
190+
191+ let data = & mut data. as_ref ( ) ;
192+
193+ let iter = BooleanIter :: new ( data, 8 )
194+ . collect :: < Result < Vec < _ > , Error > > ( )
195+ . unwrap ( ) ;
196+ assert_eq ! (
197+ iter,
198+ vec![ true , false , false , false , false , false , false , false , ]
199+ )
200+ }
201+ }
0 commit comments