102 lines
3.2 KiB
Rust
102 lines
3.2 KiB
Rust
use tool_helper::{Input, Output};
|
|
use std::io::Read;
|
|
pub use tool_helper::Error;
|
|
|
|
pub enum LineFeed {
|
|
Unix,
|
|
Windows
|
|
}
|
|
|
|
pub enum FileType {
|
|
CHeader,
|
|
CSource,
|
|
CPPHeader,
|
|
CPPSource,
|
|
}
|
|
|
|
pub struct Configuration {
|
|
pub file_name: String,
|
|
pub data_name: String,
|
|
pub line_feed: LineFeed,
|
|
pub file_type: FileType,
|
|
}
|
|
|
|
struct FileDeclarations<'a> {
|
|
include: &'a str,
|
|
var_type: &'a str,
|
|
}
|
|
|
|
const UNIX_LINEFEED: &'static str = "\n";
|
|
const WINDOWS_LINEFEED: &'static str = "\r\n";
|
|
|
|
const C_DECLARATIONS: FileDeclarations = FileDeclarations{include: "", var_type: "char"};
|
|
const CPP_DECLARATIONS: FileDeclarations = FileDeclarations{include: "#include <stdint.h>", var_type: "uint8_t"};
|
|
|
|
fn output_bytes(input: Input, output: &mut Output, line_feed: &str) -> Result<(), std::io::Error> {
|
|
let mut byte_line_count = 1;
|
|
let mut bytes = input.bytes();
|
|
|
|
if let Some(byte) = bytes.next() {
|
|
write!(output, "\t{:#04X}", byte?)?;
|
|
|
|
for byte in bytes {
|
|
write!(output, ", {:#04X}", byte?)?;
|
|
byte_line_count += 1;
|
|
|
|
if byte_line_count >= 16 {
|
|
write!(output, "{}\t", line_feed)?;
|
|
byte_line_count = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn write_header_file(input: Input, output: &mut Output, file_name: String, declarations: &FileDeclarations, data_name: String, line_feed: &str) -> Result<(), std::io::Error> {
|
|
let file_name = file_name.to_uppercase().replace('.', "_");
|
|
|
|
write!(output, "#ifndef __{}__{}", file_name, line_feed)?;
|
|
write!(output, "#define __{}__{}", file_name, line_feed)?;
|
|
write!(output, "{}{}{}", declarations.include, line_feed, line_feed)?;
|
|
write!(output, "static const {} {}[] = {{{}", declarations.var_type, data_name, line_feed)?;
|
|
|
|
output_bytes(input, output, line_feed)?;
|
|
|
|
write!(output, "{}}};{}", line_feed, line_feed)?;
|
|
write!(output, "#endif // !__{}__{}", file_name, line_feed)
|
|
}
|
|
|
|
fn write_source_file(input: Input, output: &mut Output, declarations: &FileDeclarations, data_name: String, line_feed: &str) -> Result<(), std::io::Error> {
|
|
write!(output, "{}{}{}", declarations.include, line_feed, line_feed)?;
|
|
write!(output, "const {} {}[] = {{{}", declarations.var_type, data_name, line_feed)?;
|
|
|
|
output_bytes(input, output, line_feed)?;
|
|
|
|
write!(output, "{}}};", line_feed)
|
|
}
|
|
|
|
pub fn convert(cfg: Configuration, input: Input, mut output: Output) -> Result<(), Error> {
|
|
let line_feed = {
|
|
match cfg.line_feed {
|
|
LineFeed::Windows => WINDOWS_LINEFEED,
|
|
LineFeed::Unix => UNIX_LINEFEED
|
|
}
|
|
};
|
|
let (declarations, is_source_file) = {
|
|
match cfg.file_type {
|
|
FileType::CHeader => (&C_DECLARATIONS, false),
|
|
FileType::CSource => (&C_DECLARATIONS, true),
|
|
FileType::CPPHeader => (&CPP_DECLARATIONS, false),
|
|
FileType::CPPSource => (&CPP_DECLARATIONS, true),
|
|
}
|
|
};
|
|
|
|
if is_source_file {
|
|
Error::try_or_new(write_source_file(input, &mut output, declarations, cfg.data_name, line_feed), None)
|
|
}
|
|
|
|
else {
|
|
Error::try_or_new(write_header_file(input, &mut output, cfg.file_name, declarations, cfg.data_name, line_feed), None)
|
|
}
|
|
} |