diff --git a/src/record_iterator.rs b/src/record_iterator.rs index d9d5efa..bbe0767 100644 --- a/src/record_iterator.rs +++ b/src/record_iterator.rs @@ -6,25 +6,36 @@ pub struct RecordIterator<'a> { r701: &'a mut R701, input_buffer: Vec, sequence_number: u16, - record_count: u16, total_records: u16, + record_count: u16, } impl<'a> RecordIterator<'a> { pub fn from(r701: &'a mut R701) -> Result { - // Ping the endpoint - r701.ping()?; - // Get the total number of records let total_records = r701.get_total_record_count()?; + // The endpoint expects the first block of records to be sent first + r701.get_record_bytes(total_records, 0)?; + + // Calculate the sequence number of the last record and the position of + // the last useful byte + let sequence_number = total_records * 12 / 1024; + let last_byte = (total_records * 12 % 1024) as usize; + + // Get the last records and cut out all the trailing `ff` bytes + let input_buffer = r701 + .get_record_bytes(total_records, sequence_number)? + .drain(..last_byte) + .collect::>(); + // Return a new Iterator Ok(Self { r701, - input_buffer: Vec::new(), - record_count: 0, - sequence_number: 0, + input_buffer, + sequence_number, total_records, + record_count: total_records, }) } } @@ -33,32 +44,39 @@ impl<'a> Iterator for RecordIterator<'a> { type Item = Record; fn next(&mut self) -> Option { - self.record_count += 1; - - // If we exceeded the total number of records, return None - if self.record_count > self.total_records { + // Stop iterating when there are no more records + if self.record_count == 0 { return None; } - // If the buffer is empty, make another request to the endpoint asking - // for more data + self.record_count -= 1; + + // If the input buffer is almost empty, make another request to the + // endpoint asking for more data if self.input_buffer.len() < 12 { - let bytes = &mut self + // If the buffer is almost empty but the sequence number is already + // zero, stop iterating + if self.sequence_number == 0 { + return None; + } + + self.sequence_number -= 1; + + // Request new bytes + let bytes = self .r701 .get_record_bytes(self.total_records, self.sequence_number) .ok()?; - self.input_buffer.append(bytes); - self.sequence_number += 1; - } - - // If the record bytes are set to `ff ff ff ff ff ff ff ff ff ff ff ff`, - // return None - if self.input_buffer[..12] == [0xff_u8; 12] { - return None; + // Put the bytes at the start of the vector + self.input_buffer.splice(0..0, bytes.iter().copied()); } // Return a new Record - self.input_buffer.drain(..12).as_slice().try_into().ok() + self.input_buffer + .drain(self.input_buffer.len() - 12..) + .as_slice() + .try_into() + .ok() } }