X-Git-Url: http://git.code-monkey.de/?p=gps-watch.git;a=blobdiff_plain;f=src%2Fcommon%2Flogger.rs;h=23c40a140d45c76945a069220b55e5ca495420d9;hp=d83d2391bfe1a6261dc2bb312e2a6a288d26ba16;hb=f68ab85d65e9053868ce022e997b3834d6812f59;hpb=9c56bca3b719a7e44074225a99d9f97fd05466d3 diff --git a/src/common/logger.rs b/src/common/logger.rs index d83d239..23c40a1 100644 --- a/src/common/logger.rs +++ b/src/common/logger.rs @@ -25,12 +25,20 @@ use gps::TimeAndPos; use storage::Storage; use varint; use systick::elapsed_ms; +use buffer::Buffer; +use yencode::Yencode; +use fmt::*; pub const MEMORY_SIZE: usize = 2 << 20; const SECTOR_SIZE: usize = 4 << 10; const NUM_SECTORS: usize = MEMORY_SIZE / SECTOR_SIZE; +#[derive(Clone, Copy, PartialEq, Debug)] +pub enum Error { + NoSuchRecording, +} + enum SectorFlag { InUse = 1 << 0, DataRecord = 1 << 1, @@ -72,6 +80,10 @@ impl SectorHeader { (self.flags & mask) == value } + + fn belongs_to(&self, recording_id: u16) -> bool { + self.is_in_use() && self.recording_id == recording_id + } } #[derive(Clone, Copy)] @@ -557,4 +569,61 @@ impl<'a> Logger<'a> { self.write_buffer_offset += num_bytes_written; } + + /// + /// Retrieve recording @p recording_id and + /// write it to @p tx_buf in yencoded form. + pub fn get_recording(&mut self, recording_id: u16, + tx_buf: &mut Buffer) -> Result<(), Error> { + if recording_id == 0 { + return Err(Error::NoSuchRecording); + } + + if let Some(found_index) = self.sector_header_iter().find(|&index| { + let sector_header = &self.sector_header[index as usize]; + + sector_header.recording_id == recording_id && + sector_header.starts_recording() + }) { + let mut filename = [b' '; 29]; + + filename[0..].copy_from_slice(b"gps-watch-recording-XXXXX.bin"); + + fmt_u32_pad(&mut filename[20..], recording_id as u32, 5, b'0'); + + let mut yenc = Yencode::new(tx_buf); + + yenc.start(&filename); + + let format_version = 1u8; + yenc.data(&[format_version]); + + let mut next_sector = found_index as usize; + + for _ in 0..NUM_SECTORS { + let address = next_sector * SECTOR_SIZE; + let mut buf = [0u8; SECTOR_SIZE]; + + self.storage.read(address, &mut buf); + + // Skip flags and recording ID. + yenc.data(&buf[4..]); + + next_sector += 1; + next_sector &= NUM_SECTORS - 1; + + if !self.sector_header[next_sector].belongs_to(recording_id) { + break; + } + } + + yenc.finish(); + + tx_buf.flush(); + + Ok(()) + } else { + Err(Error::NoSuchRecording) + } + } }