@@ -75,6 +75,48 @@ impl<R: io::Read> io::BufRead for Utf8BytesReader<R> {
75
75
}
76
76
}
77
77
78
+ ///
79
+ #[ derive( Debug ) ]
80
+ pub struct ValidatingReader < R > {
81
+ reader : R ,
82
+ leftover_bytes_buf : [ u8 ; 7 ] ,
83
+ len : u8 ,
84
+ }
85
+
86
+ impl < R : io:: Read > ValidatingReader < R > {
87
+ ///
88
+ pub fn new ( reader : R ) -> Self {
89
+ Self {
90
+ reader,
91
+ leftover_bytes_buf : [ 0 ; 7 ] ,
92
+ len : 0 ,
93
+ }
94
+ }
95
+ }
96
+
97
+ impl < R : io:: Read > io:: Read for ValidatingReader < R > {
98
+ fn read ( & mut self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
99
+ buf[ ..self . len . into ( ) ] . copy_from_slice ( & self . leftover_bytes_buf [ ..self . len . into ( ) ] ) ;
100
+ let ( _leftovers, copy_dest) = buf. split_at_mut ( self . len . into ( ) ) ;
101
+ let amt = self . reader . read ( copy_dest) ?;
102
+
103
+ match std:: str:: from_utf8 ( buf) {
104
+ Ok ( _) => Ok ( amt) ,
105
+ Err ( err) => {
106
+ let ( valid, after_valid) = buf. split_at ( err. valid_up_to ( ) ) ;
107
+ self . leftover_bytes_buf [ ..after_valid. len ( ) ] . copy_from_slice ( after_valid) ;
108
+ self . len = after_valid. len ( ) as u8 ;
109
+ Ok ( valid. len ( ) )
110
+ }
111
+ }
112
+
113
+ // error::const_io_error!(
114
+ // ErrorKind::InvalidData,
115
+ // "stream did not contain valid UTF-8"
116
+ // )
117
+ }
118
+ }
119
+
78
120
/// Decodes the provided bytes using the specified encoding.
79
121
///
80
122
/// Returns an error in case of malformed or non-representable sequences in the `bytes`.
@@ -126,3 +168,32 @@ pub fn detect_encoding(bytes: &[u8]) -> Option<(&'static Encoding, usize)> {
126
168
_ => None ,
127
169
}
128
170
}
171
+
172
+ #[ cfg( test) ]
173
+ mod test {
174
+ use std:: io:: Read ;
175
+
176
+ use super :: * ;
177
+
178
+ #[ track_caller]
179
+ fn test_valiate_input ( input : & [ u8 ] ) {
180
+ let mut reader = ValidatingReader :: new ( input) ;
181
+ let mut buf = [ 0 ; 100 ] ;
182
+ assert_eq ! ( reader. read( & mut buf) . unwrap( ) , input. len( ) ) ;
183
+ }
184
+
185
+ mod decoding_reader {
186
+
187
+ }
188
+
189
+ mod validating_reader {
190
+
191
+ }
192
+
193
+ // #[test]
194
+ // fn test() {
195
+ // test_input(b"asdf");
196
+ // test_input(b"\x82\xA0\x82\xA2\x82\xA4");
197
+ // test_input(b"\xEF\xBB\xBFfoo\xFFbar");
198
+ // }
199
+ }
0 commit comments