1use crate::{checksum::ra2_crc, constants::XCC_HEADER_SIZE};
2use ra2_types::Ra2Error;
3use std::{collections::BTreeMap, ffi::OsStr, io::Write, path::Path};
4
5mod reader;
6mod writer;
7
8#[derive(Clone, Debug, Default)]
10pub struct MixDatabase {
11 map: BTreeMap<u32, String>,
12}
13
14impl MixDatabase {
15 pub fn decode(dat: &[u8]) -> Result<MixDatabase, Ra2Error> {
16 let mut out = MixDatabase::default();
17 let names = get_filenames_from_mix_db(dat);
18 names.into_iter().for_each(|name| out.add(name));
19 Ok(out)
20 }
21 pub fn load(path: &Path) -> Result<MixDatabase, Ra2Error> {
22 match path.extension() {
23 #[cfg(feature = "toml")]
24 Some(s) if s.eq("toml") => {
25 let text = std::fs::read_to_string(path)?;
26 Ok(Self { map: toml::from_str(&text)? })
27 }
28 _ => Ok(Self::decode(&std::fs::read(path)?)?),
29 }
30 }
31}
32
33impl MixDatabase {
34 #[cfg(feature = "serde_json")]
35 pub fn encode_json(self) -> Result<String, Ra2Error> {
36 Ok(serde_json::to_string(&self.map)?)
37 }
38
39 pub fn save(&self, path: &Path) -> Result<(), Ra2Error> {
40 match path.extension() {
41 #[cfg(feature = "toml")]
42 Some(s) if s.eq("toml") => {
43 let mut file = std::fs::File::create(path)?;
44 for (crc_id, filename) in &self.map {
45 writeln!(file, "{} = {:?}", crc_id, filename)?;
46 }
47 }
48 _ => {}
49 }
50 Ok(())
51 }
52}
53
54impl MixDatabase {
55 pub fn get(&self, crc_id: u32) -> Option<&String> {
56 self.map.get(&crc_id)
57 }
58 pub fn add(&mut self, filename: String) {
59 self.map.insert(ra2_crc(&filename), filename);
60 }
61}
62
63fn get_filenames_from_mix_db(mix_db_file_data: &[u8]) -> Vec<String> {
65 let mut filenames = Vec::new();
66 let mut start = XCC_HEADER_SIZE;
67
68 while start < mix_db_file_data.len() {
69 let mut end = start;
70 while end < mix_db_file_data.len() && mix_db_file_data[end] != 0 {
71 end += 1;
72 }
73
74 if start < end {
75 if let Ok(filename) = std::str::from_utf8(&mix_db_file_data[start..end]) {
76 filenames.push(filename.to_string());
77 }
78 }
79
80 end += 1; start = end;
82 }
83
84 filenames
85}