diff --git a/libconfig/src/lib.rs b/libconfig/src/lib.rs index 4e5ff30..d0543a9 100644 --- a/libconfig/src/lib.rs +++ b/libconfig/src/lib.rs @@ -3,7 +3,7 @@ extern crate alloc; use core::fmt; use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc}; -use core_io::{self as io, BufRead, BufReader, Read}; +use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, SeekFrom}; use libboard_zynq::sdio; pub mod sd_reader; @@ -56,9 +56,9 @@ fn parse_config<'a>( buffer: &mut Vec, file: fatfs::File, ) -> Result<'a, ()> { - let prefix = [key, "="].concat(); + let prefix = [key, "="].concat().to_lowercase(); for line in BufReader::new(file).lines() { - let line = line?; + let line = line?.to_lowercase(); if line.starts_with(&prefix) { buffer.extend(line[prefix.len()..].as_bytes()); return Ok(()); @@ -71,6 +71,8 @@ pub struct Config { fs: Option>>, } +const NEWLINE: &[u8] = b"\n"; + impl Config { pub fn new() -> Result<'static, Self> { let sdio = sdio::Sdio::sdio0(true); @@ -112,4 +114,60 @@ impl Config { pub fn read_str<'b>(&self, key: &'b str) -> Result<'b, String> { Ok(String::from_utf8(self.read(key)?)?) } + + pub fn remove<'b>(&self, key: &'b str) -> Result<'b, ()> { + if let Some(fs) = &self.fs { + let root_dir = fs.root_dir(); + match root_dir.remove(&["/CONFIG/", key, ".BIN"].concat()) { + Ok(()) => Ok(()), + Err(_) => { + let prefix = [key, "="].concat().to_lowercase(); + match root_dir.create_file("/CONFIG.TXT") { + Ok(mut f) => { + let mut buffer = String::new(); + f.read_to_string(&mut buffer)?; + f.seek(SeekFrom::Start(0))?; + f.truncate()?; + for line in buffer.lines() { + if line.len() > 0 && !line.to_lowercase().starts_with(&prefix) { + f.write(line.as_bytes())?; + f.write(NEWLINE)?; + } + } + Ok(()) + }, + Err(_) => Err(Error::KeyNotFoundError(key)) + } + } + } + } else { + Err(Error::NoConfig) + } + } + + pub fn write<'b>(&self, key: &'b str, value: Vec) -> Result<'b, ()> { + if self.fs.is_none() { + return Err(Error::NoConfig); + } + let fs = self.fs.as_ref().unwrap(); + let root_dir = fs.root_dir(); + let is_str = value.len() <= 100 && value.is_ascii() && !value.contains(&b'\n'); + if key == "boot" { + let mut f = root_dir.create_file("/BOOT.BIN")?; + f.truncate()?; + f.write_all(&value)?; + drop(f); + } else { + let _ = self.remove(key); + if is_str { + let mut f = root_dir.create_file("/CONFIG.TXT")?; + f.seek(SeekFrom::End(0))?; + write!(f, "{}={}\n", key, String::from_utf8(value).unwrap())?; + } else { + let mut f = root_dir.create_file(&["/CONFIG/", key, ".BIN"].concat())?; + f.write_all(&value)?; + } + } + Ok(()) + } }