(&mut self, n: usize, vm: &VirtualMachine)
| 1208 | } |
| 1209 | |
| 1210 | fn read_generic(&mut self, n: usize, vm: &VirtualMachine) -> PyResult<Option<Vec<u8>>> { |
| 1211 | if let Some(fast) = self.read_fast(n) { |
| 1212 | return Ok(Some(fast)); |
| 1213 | } |
| 1214 | |
| 1215 | let current_size = self.readahead() as usize; |
| 1216 | |
| 1217 | let mut out = vec![0u8; n]; |
| 1218 | let mut remaining = n; |
| 1219 | let mut written = 0; |
| 1220 | if current_size > 0 { |
| 1221 | let slice = self.active_read_slice(); |
| 1222 | out[..slice.len()].copy_from_slice(slice); |
| 1223 | remaining -= current_size; |
| 1224 | written += current_size; |
| 1225 | self.pos += current_size as Offset; |
| 1226 | } |
| 1227 | if self.writable() { |
| 1228 | self.flush_rewind(vm)?; |
| 1229 | } |
| 1230 | self.reset_read(); |
| 1231 | macro_rules! handle_opt_read { |
| 1232 | ($x:expr) => { |
| 1233 | match ($x, written > 0) { |
| 1234 | (Some(0), _) | (None, true) => { |
| 1235 | out.truncate(written); |
| 1236 | return Ok(Some(out)); |
| 1237 | } |
| 1238 | (Some(r), _) => r, |
| 1239 | (None, _) => return Ok(None), |
| 1240 | } |
| 1241 | }; |
| 1242 | } |
| 1243 | while remaining > 0 && !self.buffer.is_empty() { |
| 1244 | // MINUS_LAST_BLOCK() in CPython |
| 1245 | let r = self.buffer.len() * (remaining / self.buffer.len()); |
| 1246 | if r == 0 { |
| 1247 | break; |
| 1248 | } |
| 1249 | let r = self.raw_read(Either::A(Some(&mut out)), written..written + r, vm)?; |
| 1250 | let r = handle_opt_read!(r); |
| 1251 | remaining -= r; |
| 1252 | written += r; |
| 1253 | } |
| 1254 | self.pos = 0; |
| 1255 | self.raw_pos = 0; |
| 1256 | self.read_end = 0; |
| 1257 | |
| 1258 | while remaining > 0 && (self.read_end as usize) < self.buffer.len() { |
| 1259 | let r = handle_opt_read!(self.fill_buffer(vm)?); |
| 1260 | if remaining > r { |
| 1261 | out[written..][..r].copy_from_slice(&self.buffer[self.pos as usize..][..r]); |
| 1262 | written += r; |
| 1263 | self.pos += r as Offset; |
| 1264 | remaining -= r; |
| 1265 | } else if remaining > 0 { |
| 1266 | out[written..][..remaining] |
| 1267 | .copy_from_slice(&self.buffer[self.pos as usize..][..remaining]); |
no test coverage detected