From 35d3c1127db888eff203d4651b3db14d6125f2f4 Mon Sep 17 00:00:00 2001 From: alterwain Date: Mon, 3 Feb 2025 18:03:14 +0300 Subject: [PATCH] modified: Cargo.toml modified: src/main.rs new file: src/xml.rs --- Cargo.toml | 2 +- src/main.rs | 105 ++++++++++++++++++++++------------------------------ src/xml.rs | 7 ++++ 3 files changed, 53 insertions(+), 61 deletions(-) create mode 100644 src/xml.rs diff --git a/Cargo.toml b/Cargo.toml index c7a5140..8ce067f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" [dependencies] env_logger = "0.9" log = "0.4.20" -rkyv = { version = "0.8.10", features = ["unaligned", "big_endian"]} +rkyv = { version = "0.8.10", features = ["unaligned", "little_endian"]} diff --git a/src/main.rs b/src/main.rs index 77bb0e7..b76dedf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ use env_logger::Builder; use log::{error, info, LevelFilter}; use rkyv::{deserialize, rancor::Error, Archive, Deserialize, Serialize}; +mod xml; + enum ChunkType { Database, DataSet, @@ -33,11 +35,17 @@ impl From<[u8; 4]> for ChunkType { } } +#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] +#[rkyv(compare(PartialEq), derive(Debug))] +struct ChunkHeader { + chunk_type: [u8; 4], + end_of_chunk: u32, + children_count: u32 +} + #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct Database { - header_length: u32, - total_length: u32, unknown: u32, version: u32, children_count: u32, @@ -51,16 +59,12 @@ struct Database { #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct DataSet { - header_length: u32, - total_length: u32, data_type: u32 } #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct AlbumItem { - header_length: u32, - total_length: u32, // length of header + all child records number_of_strings: u32, unknown: u16, album_id_for_track: u16, @@ -71,8 +75,6 @@ struct AlbumItem { #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct TrackItem { - header_length: u32, - total_length: u32, // length of header + all child records number_of_strings: u32, // number of mhod's count unique_id: u32, visible: u32, @@ -148,8 +150,6 @@ struct TrackItem { #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct Entry { // mhod - header_length: u32, - total_length: u32, entry_type: u32, unk1: u32, unk2: u32, @@ -162,8 +162,6 @@ struct Entry { // mhod #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[rkyv(compare(PartialEq), derive(Debug))] struct Playlist { - header_length: u32, - total_length: u32, // length of header + all child records data_object_child_count: u32, playlist_item_count: u32, is_master_playlist_flag: u8, @@ -176,13 +174,6 @@ struct Playlist { list_sort_order: u32 } -#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] -#[rkyv(compare(PartialEq), derive(Debug))] -struct Header { - header_length: u32, - total_length: u32 -} - enum ChunkState { Header, Data @@ -190,83 +181,77 @@ enum ChunkState { fn db(data: &[u8]) { let mut state = ChunkState::Header; - let mut chunk_type = None; + let mut chunk_header = None; let mut i = 0; while i < data.len() { state = match state { ChunkState::Header => { - let a: [u8; 4] = data[i..i+4].try_into().unwrap(); - chunk_type = Some(ChunkType::from(a)); - i += 4; + chunk_header = Some(rkyv::access::(&data[i..i+12]).unwrap()); + i += 12; ChunkState::Data }, ChunkState::Data => { let mut u = 0; - match chunk_type.unwrap() { + let header = chunk_header.unwrap(); + match ChunkType::from(header.chunk_type) { ChunkType::Database => { - let db = rkyv::access::(&data[i..i+std::mem::size_of::()]).unwrap(); - info!("val: {:?}", db); - info!("i: {}", data[i]); - u = usize::try_from(db.header_length).unwrap() - 4; + info!("Db header: {:?}", header); + u = usize::try_from(header.end_of_chunk).unwrap() - 12; + info!("val: {:?}", rkyv::access::(&data[i..i+u]).unwrap()); }, ChunkType::DataSet => { - let ds = rkyv::access::(&data[i..i+std::mem::size_of::()]).unwrap(); - info!("val: {:?}", ds); - u = usize::try_from(ds.total_length).unwrap() - 4; + u = usize::try_from(header.end_of_chunk).unwrap() - 12; + info!("val: {:?}", rkyv::access::(&data[i..i+u]).unwrap()); }, ChunkType::AlbumList => { info!("AlbumList"); - let header = rkyv::access::(&data[i..i+std::mem::size_of::
()]).unwrap(); - u = usize::try_from(header.total_length).unwrap() - 4; + u = usize::try_from(header.end_of_chunk).unwrap() - 12; }, ChunkType::AlbumItem => { - let ai = rkyv::access::(&data[i..i+std::mem::size_of::()]).unwrap(); - info!("val: {:?}", ai); - u = usize::try_from(ai.total_length).unwrap() - 4; + u = usize::try_from(header.end_of_chunk).unwrap() - 12; + info!("val: {:?}", rkyv::access::(&data[i..i+u]).unwrap()); }, ChunkType::TrackList => { info!("TrackList"); - let header = rkyv::access::(&data[i..i+std::mem::size_of::
()]).unwrap(); - u = usize::try_from(header.total_length).unwrap() - 4; + u = usize::try_from(header.end_of_chunk).unwrap() - 12; }, ChunkType::TrackItem => { - let ti = rkyv::access::(&data[i..i+std::mem::size_of::()]).unwrap(); - info!("val: {:?}", ti); - u = usize::try_from(ti.total_length).unwrap() - 4; + u = usize::try_from(header.end_of_chunk).unwrap() - 12; + info!("val: {:?}", rkyv::access::(&data[i..i+u]).unwrap()); }, ChunkType::StringTypes => { - let header = rkyv::access::(&data[i..i+std::mem::size_of::
()]).unwrap(); - u = usize::try_from(header.header_length).unwrap() - 4; - let header_offset: usize = (header.total_length + 4) as usize; - let str_end: usize = (header.header_length - 4) as usize; + u = usize::try_from(header.children_count).unwrap() - 12; + let header_offset: usize = (header.end_of_chunk + 4) as usize; + let str_end: usize = (header.children_count - 12) as usize; let entry = rkyv::access::(&data[i..i+28]).unwrap(); info!("val: {:?}", &entry); - let mut bytes = Vec::new(); + if entry.entry_type <= 15 { + let mut bytes = Vec::new(); - let mut h = i+header_offset; - while h < i+str_end { - if data[h] != 0 { - bytes.push(data[h]); + let mut h = i+header_offset; + while h < i+str_end { + if data[h] != 0 { + bytes.push(data[h]); + } + h+=1; } - h+=1; + let g = String::from_utf8(bytes).unwrap(); + info!("str: {}", g); } - let g = String::from_utf8(bytes).unwrap(); - info!("str: {}", g); }, ChunkType::PlaylistList => { - let header = rkyv::access::(&data[i..i+std::mem::size_of::
()]).unwrap(); - info!("Playlists count: {}", header.header_length); - u = usize::try_from(header.total_length).unwrap() - 4; + info!("Playlists count: {}", header.children_count); + u = usize::try_from(header.end_of_chunk).unwrap() - 12; }, ChunkType::Playlist => { - let playlist = rkyv::access::(&data[i..i+std::mem::size_of::()]).unwrap(); + u = usize::try_from(header.end_of_chunk).unwrap() - 12; + let playlist = rkyv::access::(&data[i..i+u]).unwrap(); info!("playlist: {:?}", playlist); - u = usize::try_from(playlist.total_length).unwrap() - 4; }, - _ => return + _ => { u = 1; } } i += u; - chunk_type = None; + chunk_header = None; ChunkState::Header } } diff --git a/src/xml.rs b/src/xml.rs new file mode 100644 index 0000000..f3809eb --- /dev/null +++ b/src/xml.rs @@ -0,0 +1,7 @@ +struct Database { + +} + +trait Child { + +} \ No newline at end of file