diff --git a/Cargo.toml b/Cargo.toml index c50e23d..8e88f1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,6 @@ version = "0.1.0" edition = "2021" authors = ["alterwain"] -[lib] -crate-type = ["staticlib", "cdylib", "lib"] - [dependencies] env_logger = "0.9" log = "0.4.20" diff --git a/outdb b/outdb new file mode 100644 index 0000000..59bfd87 Binary files /dev/null and b/outdb differ diff --git a/src/lib.rs b/src/main.rs similarity index 81% rename from src/lib.rs rename to src/main.rs index 9c0cb46..e03961c 100644 --- a/src/lib.rs +++ b/src/main.rs @@ -390,52 +390,89 @@ fn x_args_to_bytes(args: &Vec) -> Vec { unknown: 0, unk4: 0 }).unwrap(); - b = [b, s].concat(); + let h = bincode::serialize(&ChunkHeader { + chunk_type: ChunkType::StringTypes.into(), + end_of_chunk: 0x18, + children_count: 0x18 + s.len() as u32 + }).unwrap(); + b = [h, b, s].concat(); return b; }) .flatten() .collect() } +fn generate_header(ct: ChunkType, header_size: usize, data_len: usize) -> Vec { + let header_size = 12 + header_size as u32; + let header = ChunkHeader{ chunk_type: ct.into(), end_of_chunk: header_size, children_count: header_size + data_len as u32}; + bincode::serialize(&header).unwrap() +} +/* +[lib] +crate-type = ["staticlib", "cdylib", "lib"] +*/ + fn to_bytes(xdb: XDatabase) -> Vec { let mut bytes: Vec = Vec::new(); - bytes = [bytes, bincode::serialize(&xdb.header.unwrap()).unwrap()].concat(); - bytes = [bytes, bincode::serialize(&xdb.data.unwrap()).unwrap()].concat(); for i in 0..xdb.children.len() { let data_set = xdb.children.get(i).unwrap(); - bytes = [bytes, bincode::serialize(&data_set.header).unwrap()].concat(); - bytes = [bytes, bincode::serialize(&data_set.data).unwrap()].concat(); match &data_set.child { XSomeList::Playlists(playlists) => { + let mut pl_bytes = Vec::new(); for u in 0..playlists.len() { let playlist = playlists.get(u).unwrap(); - bytes = [bytes, bincode::serialize(&playlist.header).unwrap()].concat(); - bytes = [bytes, bincode::serialize(&playlist.data).unwrap()].concat(); - bytes = [bytes, x_args_to_bytes(&playlist.args)].concat(); + let mut args = x_args_to_bytes(&playlist.args); + pl_bytes.append(&mut generate_header(ChunkType::Playlist, std::mem::size_of::(),args.len())); + pl_bytes.append(&mut bincode::serialize(&playlist.data).unwrap()); + pl_bytes.append(&mut args); } + let mhlp = ChunkHeader { chunk_type: ChunkType::PlaylistList.into(), end_of_chunk: 12, children_count: playlists.len() as u32 }; + let mut mhlp = bincode::serialize(&mhlp).unwrap(); + bytes.append(&mut generate_header(ChunkType::DataSet, 4, mhlp.len())); + bytes.append(&mut bincode::serialize(&data_set.data).unwrap()); + bytes.append(&mut mhlp); + bytes.append(&mut pl_bytes); }, XSomeList::AlbumList(albums) => { + let mut al_bytes = Vec::new(); for u in 0..albums.len() { let album = albums.get(u).unwrap(); - bytes = [bytes, bincode::serialize(&album.header).unwrap()].concat(); - bytes = [bytes, bincode::serialize(&album.data).unwrap()].concat(); - bytes = [bytes, x_args_to_bytes(&album.args)].concat(); + let mut args = x_args_to_bytes(&album.args); + al_bytes.append(&mut generate_header(ChunkType::AlbumItem, std::mem::size_of::(),args.len())); + al_bytes.append(&mut bincode::serialize(&album.data).unwrap()); + al_bytes.append(&mut args); } + let mhla = ChunkHeader { chunk_type: ChunkType::AlbumList.into(), end_of_chunk: 12, children_count: albums.len() as u32 }; + let mut mhla = bincode::serialize(&mhla).unwrap(); + bytes.append(&mut generate_header(ChunkType::DataSet, 4, mhla.len())); + bytes.append(&mut bincode::serialize(&data_set.data).unwrap()); + bytes.append(&mut mhla); + bytes.append(&mut al_bytes); }, XSomeList::TrackList(tracks) => { + let mut tr_bytes = Vec::new(); for u in 0..tracks.len() { let track = tracks.get(u).unwrap(); - bytes = [bytes, bincode::serialize(&track.header).unwrap()].concat(); - bytes = [bytes, bincode::serialize(&track.data).unwrap()].concat(); - bytes = [bytes, x_args_to_bytes(&track.args)].concat(); + let mut args = x_args_to_bytes(&track.args); + tr_bytes.append(&mut generate_header(ChunkType::TrackItem, std::mem::size_of::(),args.len())); + tr_bytes.append(&mut bincode::serialize(&track.data).unwrap()); + tr_bytes.append(&mut args); } + let mhlt = ChunkHeader { chunk_type: ChunkType::TrackList.into(), end_of_chunk: 12, children_count: tracks.len() as u32 }; + let mut mhlt = bincode::serialize(&mhlt).unwrap(); + bytes.append(&mut generate_header(ChunkType::DataSet, 4, mhlt.len())); + bytes.append(&mut bincode::serialize(&data_set.data).unwrap()); + bytes.append(&mut mhlt); + bytes.append(&mut tr_bytes); } } } + bytes = [bincode::serialize(&xdb.data.unwrap()).unwrap(), bytes].concat(); + bytes = [generate_header(ChunkType::Database, std::mem::size_of::(), bytes.len()), bytes].concat(); bytes } -/*fn main() { +fn main() { // Initialize the logger with 'info' as the default level Builder::new() @@ -447,10 +484,12 @@ fn to_bytes(xdb: XDatabase) -> Vec { match f.read_to_end(&mut buf) { Ok(n) => { let data = &buf[..n]; - parse_bytes(data); + let xdb = parse_bytes(data); + let mut op = File::create("outdb").unwrap(); + info!("Write res: {:?}", op.write(&to_bytes(xdb))); }, Err(e) => { error!("Error: {}",e); } } -}*/ +}