add shiftjis as possible data type for symbols (#95)

* add shiftjis as possible data type for symbols

* usage of anyhow:bail! -> bail!

* revise output of sjis strings

* rename shiftjis internally, symbols now uses sjis instead of shiftjis

* remove sjis decoding error check as the output is a comment

* run cargo fmt
This commit is contained in:
Rainchus 2025-04-17 00:59:21 -05:00 committed by GitHub
parent 614d4f2efc
commit 18987ed330
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 54 additions and 0 deletions

1
Cargo.lock generated
View File

@ -363,6 +363,7 @@ dependencies = [
"cwextab",
"dyn-clone",
"enable-ansi-support",
"encoding_rs",
"filetime",
"fixedbitset 0.5.7",
"flagset",

View File

@ -25,6 +25,7 @@ strip = "debuginfo"
codegen-units = 1
[dependencies]
encoding_rs = "0.8"
aes = "0.8"
anyhow = { version = "1.0", features = ["backtrace"] }
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "write_symbol_table" }

View File

@ -175,8 +175,10 @@ pub enum ObjDataKind {
Float,
Double,
String,
ShiftJIS,
String16,
StringTable,
ShiftJISTable,
String16Table,
Int,
Short,

View File

@ -668,6 +668,38 @@ where W: Write + ?Sized {
Ok(())
}
use encoding_rs::SHIFT_JIS;
fn write_string_shiftjis<W>(w: &mut W, data: &[u8]) -> Result<()>
where W: Write + ?Sized {
if data.last() != Some(&0x00) {
bail!("Non-terminated Shift-JIS string");
}
let raw_data = &data[..data.len() - 1];
// Decode then write SJIS as comment above byte array
let (cow, _, _) = SHIFT_JIS.decode(raw_data);
write!(w, "\t# ")?;
for c in cow.chars() {
match c {
'#' => write!(w, "\\#")?,
_ => write!(w, "{}", c)?,
}
}
write!(w, "\n\t.byte ")?;
for (i, &b) in data.iter().enumerate() {
write!(w, "0x{:02X}", b)?;
if i + 1 != data.len() {
write!(w, ", ")?;
}
}
writeln!(w)?;
Ok(())
}
fn write_string16<W>(w: &mut W, data: &[u16]) -> Result<()>
where W: Write + ?Sized {
if matches!(data.last(), Some(&b) if b == 0) {
@ -705,6 +737,12 @@ where W: Write + ?Sized {
ObjDataKind::String => {
return write_string(w, data);
}
ObjDataKind::ShiftJIS => {
if data.is_empty() || data.last() != Some(&0x00) {
anyhow::bail!("Non-terminated Shift-JIS string");
}
return write_string_shiftjis(w, data);
}
ObjDataKind::String16 => {
if data.len() % 2 != 0 {
bail!("Attempted to write wstring with length {:#X}", data.len());
@ -734,6 +772,12 @@ where W: Write + ?Sized {
}
return Ok(());
}
ObjDataKind::ShiftJISTable => {
for slice in data.split_inclusive(|&b| b == 0) {
write_string_shiftjis(w, slice)?;
}
return Ok(());
}
_ => {}
}
let chunk_size = match data_kind {
@ -742,7 +786,9 @@ where W: Write + ?Sized {
ObjDataKind::Byte | ObjDataKind::Byte8 | ObjDataKind::Double => 8,
ObjDataKind::String
| ObjDataKind::String16
| ObjDataKind::ShiftJIS
| ObjDataKind::StringTable
| ObjDataKind::ShiftJISTable
| ObjDataKind::String16Table => unreachable!(),
};
for chunk in remain.chunks(chunk_size) {

View File

@ -329,8 +329,10 @@ fn symbol_data_kind_to_str(kind: ObjDataKind) -> Option<&'static str> {
ObjDataKind::Float => Some("float"),
ObjDataKind::Double => Some("double"),
ObjDataKind::String => Some("string"),
ObjDataKind::ShiftJIS => Some("sjis"),
ObjDataKind::String16 => Some("wstring"),
ObjDataKind::StringTable => Some("string_table"),
ObjDataKind::ShiftJISTable => Some("sjis_table"),
ObjDataKind::String16Table => Some("wstring_table"),
ObjDataKind::Int => Some("int"),
ObjDataKind::Short => Some("short"),
@ -382,8 +384,10 @@ fn symbol_data_kind_from_str(s: &str) -> Option<ObjDataKind> {
"float" => Some(ObjDataKind::Float),
"double" => Some(ObjDataKind::Double),
"string" => Some(ObjDataKind::String),
"sjis" => Some(ObjDataKind::ShiftJIS),
"wstring" => Some(ObjDataKind::String16),
"string_table" => Some(ObjDataKind::StringTable),
"sjis_table" => Some(ObjDataKind::ShiftJISTable),
"wstring_table" => Some(ObjDataKind::String16Table),
"int" => Some(ObjDataKind::Int),
"short" => Some(ObjDataKind::Short),