From f7bb3392758184b76a5d08746a7bb1627335e05f Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 18 Jun 2020 11:29:33 +0800 Subject: [PATCH] Config: implemented config struct. --- src/runtime/src/config.rs | 85 ++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/src/runtime/src/config.rs b/src/runtime/src/config.rs index 5ae22519..ab8cf1c7 100644 --- a/src/runtime/src/config.rs +++ b/src/runtime/src/config.rs @@ -1,65 +1,96 @@ -use log::info; +use crate::sd_reader; use core::fmt; -use alloc::{vec::Vec, string::String, string::FromUtf8Error}; -use core_io as io; +use alloc::{string::FromUtf8Error, string::String, vec::Vec}; +use core_io::{self as io, BufRead, BufReader, Read}; use libboard_zynq::sdio; -use crate::sd_reader; - #[derive(Debug)] -pub enum Error { +pub enum Error<'a> { SdError(sdio::sd_card::CardInitializationError), IoError(io::Error), Utf8Error(FromUtf8Error), + ConfigNotFound(&'a str), } -pub type Result = core::result::Result; +pub type Result<'a, T> = core::result::Result>; -impl fmt::Display for Error { +impl<'a> fmt::Display for Error<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Error::SdError(error) => write!(f, "SD error: {:?}", error), // TODO: Display for CardInitializationError? - Error::IoError(error) => write!(f, "I/O error: {}", error), + Error::SdError(error) => write!(f, "SD error: {}", error), + Error::IoError(error) => write!(f, "I/O error: {}", error), Error::Utf8Error(error) => write!(f, "UTF-8 error: {}", error), + Error::ConfigNotFound(name) => write!(f, "Config `{}` not found", name), } } } -impl From for Error { +impl<'a> From for Error<'a> { fn from(error: sdio::sd_card::CardInitializationError) -> Self { Error::SdError(error) } } -impl From for Error { +impl<'a> From for Error<'a> { fn from(error: io::Error) -> Self { Error::IoError(error) } } -impl From for Error { +impl<'a> From for Error<'a> { fn from(error: FromUtf8Error) -> Self { Error::Utf8Error(error) } } -pub fn read(key: &str) -> Result> { - let sdio = sdio::SDIO::sdio0(true); - let mut sd = sdio::sd_card::SdCard::from_sdio(sdio)?; - let reader = sd_reader::SdReader::new(&mut sd); - - let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?; - let root_dir = fs.root_dir(); - for entry in root_dir.iter() { - if let Ok(entry) = entry { - let bytes = entry.short_file_name_as_bytes(); - info!("{}", core::str::from_utf8(bytes).unwrap()); +fn parse_config<'a>( + key: &'a str, + buffer: &mut Vec, + file: fatfs::File, +) -> Result<'a, ()> { + let prefix = [key, "="].concat(); + for line in BufReader::new(file).lines() { + let line = line?; + if line.starts_with(&prefix) { + buffer.extend(line[prefix.len()..].as_bytes()); + return Ok(()); } } - Err(sdio::sd_card::CardInitializationError::NoCardInserted)? // TODO + Err(Error::ConfigNotFound(key)) } -pub fn read_str(key: &str) -> Result { - Ok(String::from_utf8(read(key)?)?) +pub struct Config { + fs: fatfs::FileSystem, +} + +impl Config { + pub fn new() -> Result<'static, Self> { + let sdio = sdio::SDIO::sdio0(true); + if !sdio.is_card_inserted() { + Err(sdio::sd_card::CardInitializationError::NoCardInserted)?; + } + let sd = sdio::sd_card::SdCard::from_sdio(sdio)?; + let reader = sd_reader::SdReader::new(sd); + + let fs = reader.mount_fatfs(sd_reader::PartitionEntry::Entry1)?; + Ok(Config { fs }) + } + + fn read<'b>(&mut self, key: &'b str) -> Result<'b, Vec> { + let root_dir = self.fs.root_dir(); + let mut buffer: Vec = Vec::new(); + match root_dir.open_file(&["/CONFIG/", key, ".BIN"].concat()) { + Ok(mut f) => f.read_to_end(&mut buffer).map(|v| ())?, + Err(_) => match root_dir.open_file("/CONFIG.TXT") { + Ok(f) => parse_config(key, &mut buffer, f)?, + Err(_) => return Err(Error::ConfigNotFound(key)), + }, + }; + Ok(buffer) + } + + pub fn read_str<'b>(&mut self, key: &'b str) -> Result<'b, String> { + Ok(String::from_utf8(self.read(key)?)?) + } }