Add config writing capability #99

Closed
cw wants to merge 3 commits from (deleted):master into master
1 changed files with 80 additions and 16 deletions
Showing only changes of commit 6bd4881cc5 - Show all commits

View File

@ -1,7 +1,7 @@
use crate::sd_reader; use crate::sd_reader;
use core::fmt; use core::fmt;
use alloc::{string::FromUtf8Error, string::String, vec::Vec}; use alloc::{string::FromUtf8Error, string::String, vec::Vec};
use core_io::{self as io, BufRead, BufReader, Read, Write, ErrorKind}; use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, ErrorKind, SeekFrom};
use libboard_zynq::sdio; use libboard_zynq::sdio;
@ -61,6 +61,39 @@ fn parse_config<'a>(
} }
Err(Error::KeyNotFoundError(key)) Err(Error::KeyNotFoundError(key))
} }
fn delete_old_entry<'a>(
key: &str,
file: fatfs::File<sd_reader::SdReader>,
mut file_tmp: fatfs::File<sd_reader::SdReader>,
) -> Result<'a, ()> {
let prefix = [key, "="].concat();
let buf_reader = BufReader::new(file);
for line in buf_reader.lines() {
let line = line?;
if !line.starts_with(&prefix) {
file_tmp.write_all(&[line.as_str(), "\n"].concat().as_bytes())?;
}
}
Ok(())
}
fn rename_file<'a>(dir: &fatfs::Dir<sd_reader::SdReader>, old_file_name: &str, new_file_name: &str) -> Result<'a, ()>{
{
let old_file = dir.open_file(old_file_name)?;
let mut new_file = dir.create_file(new_file_name)?;
new_file.truncate()?;
for line in BufReader::new(old_file).lines() {
let line = line?;
new_file.write_all(&[line.as_str(), "\n"].concat().as_bytes())?;
}
}
dir.remove(old_file_name)?;
Ok(())
}
pub struct Config { pub struct Config {
fs: Option<fatfs::FileSystem<sd_reader::SdReader>>, fs: Option<fatfs::FileSystem<sd_reader::SdReader>>,
@ -108,26 +141,27 @@ impl Config {
if let Some(fs) = &self.fs { if let Some(fs) = &self.fs {
let root_dir = fs.root_dir(); let root_dir = fs.root_dir();
let use_config_txt = data.is_ascii() & (data.len() <= 100);
let file_path;
let config_key_bin = &["/CONFIG/", key, ".BIN"].concat(); let config_key_bin = &["/CONFIG/", key, ".BIN"].concat();
let config_txt_tmp = "/CONFIG.TMP";
if use_config_txt { if data.is_ascii() & (data.len() <= 100) {
file_path = "/CONFIG.TXT"; match root_dir.create_file("/CONFIG.TXT") {
} else { Ok(file) => {
file_path = config_key_bin; let mut file_tmp = root_dir.create_file(config_txt_tmp)?;
} file_tmp.truncate()?;
delete_old_entry(key, file, file_tmp)?;
},
Err(e) => {
return Err(Error::IoError(e));
}
};
let mut file = match root_dir.create_file(file_path) { rename_file(&root_dir, config_txt_tmp, "/CONFIG.TXT")?;
Ok(f) => f,
Err(_) => root_dir.open_file("/CONFIG.TXT")?
};
file.truncate()?; let mut file = root_dir.open_file("/CONFIG.TXT")?;
file.write_all(&[key,"="].concat().as_bytes())?; file.seek(SeekFrom::End(0))?;
file.write_all(data.as_bytes())?; file.write_all(&["\n", key, "=", data, "\n"].concat().as_bytes())?;
if use_config_txt {
match root_dir.remove(config_key_bin) { match root_dir.remove(config_key_bin) {
Ok(_) => {}, Ok(_) => {},
Err(e) => match e.kind() { Err(e) => match e.kind() {
@ -137,6 +171,36 @@ impl Config {
} }
} }
}; };
} else {
root_dir.create_dir("/CONFIG")?;
match root_dir.create_file(config_key_bin) {
Ok(mut file) => {
file.truncate()?;
file.write_all(&[data, "\n"].concat().as_bytes())?;
},
Err(e) => {
return Err(Error::IoError(e));
}
};
let mut need_to_rename = false;
match root_dir.open_file("/CONFIG.TXT") {
Ok(file) => {
need_to_rename = true;
let mut file_tmp = root_dir.create_file(config_txt_tmp)?;
file_tmp.truncate()?;
delete_old_entry(key, file, file_tmp)?;
},
Err(e) => match e.kind() {
ErrorKind::NotFound => {},
_ => {
return Err(Error::IoError(e));
}
}
};
if need_to_rename { // docs: ensure no ref to files
rename_file(&root_dir, config_txt_tmp, "/CONFIG.TXT")?;
}
} }
Ok(()) Ok(())