Skip to content

Commit 56773a7

Browse files
committed
use mst builder for convert command
1 parent 9464862 commit 56773a7

File tree

1 file changed

+21
-59
lines changed

1 file changed

+21
-59
lines changed

fang-cli/src/actions/mst/convert.rs

+21-59
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,54 @@
11
use clap::Parser;
22
use fang::{
3-
mst::{entry::Entry, Mst, MstVersionKnown},
4-
BinReaderExt, BinWriterExt,
3+
mst::{builder::MstBuilder, entry::Entry, Mst, MstVersionKnown},
4+
BinReaderExt,
55
};
66
use std::{
7-
cell::RefCell,
87
fs::File,
9-
io::{BufReader, BufWriter, Read, Seek, SeekFrom, Write},
8+
io::{BufReader, BufWriter},
109
path::Path,
11-
rc::Rc,
1210
};
1311

1412
#[derive(Parser, Debug)]
1513
pub struct ConvertOpts {
1614
/// Path to MST
1715
#[clap(short = 'i', long)]
1816
input_path: String,
19-
/// New major version
20-
#[clap(long)]
21-
major: Option<u8>,
2217
/// New minor version
2318
#[clap(long)]
2419
minor: Option<u8>,
2520
}
2621

2722
pub fn convert_mst(opts: ConvertOpts) -> anyhow::Result<()> {
23+
// Parse the source Mst from input_path
2824
let mut in_file = BufReader::new(File::open(&opts.input_path)?);
25+
let mst = in_file.read_le::<Mst>()?;
2926

30-
let mut mst = in_file.read_le::<Mst>()?;
31-
32-
let mut content_bufs = Vec::new();
33-
for entry in mst.collect_entries() {
34-
in_file.seek(SeekFrom::Start(entry.offset() as u64))?;
35-
36-
let mut buf = vec![0u8; entry.size()];
37-
in_file.read_exact(&mut buf)?;
38-
content_bufs.push(buf);
39-
}
40-
41-
let out_path = Path::new(&opts.input_path).with_extension("convert.mst");
42-
let mut out_file = BufWriter::new(File::create(&out_path)?);
27+
// Prepare a new Mst, copying the versions and platform
28+
let mut mst_builder = MstBuilder::from_mst_empty(&mst)?;
4329

30+
// Update the Mst version with given minor version (6, 7, 8)
4431
let mut new_mst_version = *mst.body.version();
45-
new_mst_version.set_major(opts.major.unwrap_or_else(|| new_mst_version.major()));
4632
new_mst_version.set_minor(opts.minor.unwrap_or_else(|| new_mst_version.minor()));
4733
let new_version = MstVersionKnown::try_from(&new_mst_version)?;
4834

49-
mst.body = mst.body.convert(new_version);
50-
51-
let content_offset_offsets = Rc::new(RefCell::new(Vec::new()));
35+
mst_builder.set_version(&new_version);
5236

53-
out_file.write_le_args(&mst, (content_offset_offsets.clone(),))?;
54-
55-
let mut content_offsets = Vec::new();
56-
for content_buf in content_bufs {
57-
let mut pos = out_file.stream_position()?;
58-
if pos % 2048 > 0 {
59-
let padding = 2048 - pos % 2048;
60-
let padding = vec![0u8; padding as usize];
61-
out_file.write_all(&padding)?;
62-
pos = out_file.stream_position()?;
63-
}
64-
65-
content_offsets.push(pos);
66-
out_file.write_all(&content_buf)?;
67-
}
68-
69-
if let Some(min_data_offset) = content_offsets.iter().min() {
70-
out_file.seek(SeekFrom::Start(28))?;
71-
72-
let offset = *min_data_offset as u32;
73-
if mst.identifier.is_little() {
74-
out_file.write_all(&offset.to_le_bytes())?;
75-
} else {
76-
out_file.write_all(&offset.to_be_bytes())?;
77-
}
37+
// Add all the entries from the source Mst as references
38+
for entry in mst.collect_entries() {
39+
mst_builder.add_entry_file(
40+
entry.filename().to_string(),
41+
opts.input_path.clone(),
42+
entry.offset(),
43+
entry.size(),
44+
);
7845
}
7946

80-
for (pos, offset) in content_offset_offsets.borrow().iter().zip(content_offsets) {
81-
out_file.seek(SeekFrom::Start(*pos))?;
47+
// Finalize and write the Mst with contents to input_path.convert.mst
48+
let out_path = Path::new(&opts.input_path).with_extension("convert.mst");
49+
let mut out_file = BufWriter::new(File::create(&out_path)?);
8250

83-
let offset = offset as u32;
84-
if mst.identifier.is_little() {
85-
out_file.write_all(&offset.to_le_bytes())?;
86-
} else {
87-
out_file.write_all(&offset.to_be_bytes())?;
88-
}
89-
}
51+
mst_builder.write(&mut out_file)?;
9052

9153
Ok(())
9254
}

0 commit comments

Comments
 (0)