Read the next record header (30 bytes) without reading the payload. Returns `None` at EOF or first corruption. After this call, use either `read_payload()` to get the payload or `skip_payload()` to seek past it.
(&mut self)
| 66 | /// either `read_payload()` to get the payload or `skip_payload()` to |
| 67 | /// seek past it. |
| 68 | pub fn next_header(&mut self) -> Result<Option<RecordHeader>> { |
| 69 | let mut header_buf = [0u8; HEADER_SIZE]; |
| 70 | match self.read_exact(&mut header_buf) { |
| 71 | Ok(()) => {} |
| 72 | Err(WalError::Io(e)) if e.kind() == std::io::ErrorKind::UnexpectedEof => { |
| 73 | return Ok(None); |
| 74 | } |
| 75 | Err(e) => return Err(e), |
| 76 | } |
| 77 | |
| 78 | let header = RecordHeader::from_bytes(&header_buf); |
| 79 | |
| 80 | if header.validate(self.offset - HEADER_SIZE as u64).is_err() { |
| 81 | return Ok(None); |
| 82 | } |
| 83 | |
| 84 | // Check for unknown required record types. |
| 85 | let logical_type = header.logical_record_type(); |
| 86 | if crate::record::RecordType::from_raw(logical_type).is_none() |
| 87 | && crate::record::RecordType::is_required(logical_type) |
| 88 | { |
| 89 | return Err(WalError::UnknownRequiredRecordType { |
| 90 | record_type: header.record_type, |
| 91 | lsn: header.lsn, |
| 92 | }); |
| 93 | } |
| 94 | |
| 95 | Ok(Some(header)) |
| 96 | } |
| 97 | |
| 98 | /// Read the payload for a header that was just returned by `next_header()`. |
| 99 | /// |