modified: Cargo.toml

modified:   src/main.rs
	new file:   src/xml.rs
This commit is contained in:
Michael Wain 2025-02-03 18:03:14 +03:00
parent b94a19b192
commit 35d3c1127d
3 changed files with 53 additions and 61 deletions

View File

@ -6,4 +6,4 @@ edition = "2021"
[dependencies] [dependencies]
env_logger = "0.9" env_logger = "0.9"
log = "0.4.20" log = "0.4.20"
rkyv = { version = "0.8.10", features = ["unaligned", "big_endian"]} rkyv = { version = "0.8.10", features = ["unaligned", "little_endian"]}

View File

@ -3,6 +3,8 @@ use env_logger::Builder;
use log::{error, info, LevelFilter}; use log::{error, info, LevelFilter};
use rkyv::{deserialize, rancor::Error, Archive, Deserialize, Serialize}; use rkyv::{deserialize, rancor::Error, Archive, Deserialize, Serialize};
mod xml;
enum ChunkType { enum ChunkType {
Database, Database,
DataSet, 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)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct Database { struct Database {
header_length: u32,
total_length: u32,
unknown: u32, unknown: u32,
version: u32, version: u32,
children_count: u32, children_count: u32,
@ -51,16 +59,12 @@ struct Database {
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct DataSet { struct DataSet {
header_length: u32,
total_length: u32,
data_type: u32 data_type: u32
} }
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct AlbumItem { struct AlbumItem {
header_length: u32,
total_length: u32, // length of header + all child records
number_of_strings: u32, number_of_strings: u32,
unknown: u16, unknown: u16,
album_id_for_track: u16, album_id_for_track: u16,
@ -71,8 +75,6 @@ struct AlbumItem {
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct TrackItem { struct TrackItem {
header_length: u32,
total_length: u32, // length of header + all child records
number_of_strings: u32, // number of mhod's count number_of_strings: u32, // number of mhod's count
unique_id: u32, unique_id: u32,
visible: u32, visible: u32,
@ -148,8 +150,6 @@ struct TrackItem {
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct Entry { // mhod struct Entry { // mhod
header_length: u32,
total_length: u32,
entry_type: u32, entry_type: u32,
unk1: u32, unk1: u32,
unk2: u32, unk2: u32,
@ -162,8 +162,6 @@ struct Entry { // mhod
#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
#[rkyv(compare(PartialEq), derive(Debug))] #[rkyv(compare(PartialEq), derive(Debug))]
struct Playlist { struct Playlist {
header_length: u32,
total_length: u32, // length of header + all child records
data_object_child_count: u32, data_object_child_count: u32,
playlist_item_count: u32, playlist_item_count: u32,
is_master_playlist_flag: u8, is_master_playlist_flag: u8,
@ -176,13 +174,6 @@ struct Playlist {
list_sort_order: u32 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 { enum ChunkState {
Header, Header,
Data Data
@ -190,83 +181,77 @@ enum ChunkState {
fn db(data: &[u8]) { fn db(data: &[u8]) {
let mut state = ChunkState::Header; let mut state = ChunkState::Header;
let mut chunk_type = None; let mut chunk_header = None;
let mut i = 0; let mut i = 0;
while i < data.len() { while i < data.len() {
state = match state { state = match state {
ChunkState::Header => { ChunkState::Header => {
let a: [u8; 4] = data[i..i+4].try_into().unwrap(); chunk_header = Some(rkyv::access::<ArchivedChunkHeader, Error>(&data[i..i+12]).unwrap());
chunk_type = Some(ChunkType::from(a)); i += 12;
i += 4;
ChunkState::Data ChunkState::Data
}, },
ChunkState::Data => { ChunkState::Data => {
let mut u = 0; let mut u = 0;
match chunk_type.unwrap() { let header = chunk_header.unwrap();
match ChunkType::from(header.chunk_type) {
ChunkType::Database => { ChunkType::Database => {
let db = rkyv::access::<ArchivedDatabase, Error>(&data[i..i+std::mem::size_of::<Database>()]).unwrap(); info!("Db header: {:?}", header);
info!("val: {:?}", db); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
info!("i: {}", data[i]); info!("val: {:?}", rkyv::access::<ArchivedDatabase, Error>(&data[i..i+u]).unwrap());
u = usize::try_from(db.header_length).unwrap() - 4;
}, },
ChunkType::DataSet => { ChunkType::DataSet => {
let ds = rkyv::access::<ArchivedDataSet, Error>(&data[i..i+std::mem::size_of::<DataSet>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
info!("val: {:?}", ds); info!("val: {:?}", rkyv::access::<ArchivedDataSet, Error>(&data[i..i+u]).unwrap());
u = usize::try_from(ds.total_length).unwrap() - 4;
}, },
ChunkType::AlbumList => { ChunkType::AlbumList => {
info!("AlbumList"); info!("AlbumList");
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
u = usize::try_from(header.total_length).unwrap() - 4;
}, },
ChunkType::AlbumItem => { ChunkType::AlbumItem => {
let ai = rkyv::access::<ArchivedAlbumItem, Error>(&data[i..i+std::mem::size_of::<AlbumItem>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
info!("val: {:?}", ai); info!("val: {:?}", rkyv::access::<ArchivedAlbumItem, Error>(&data[i..i+u]).unwrap());
u = usize::try_from(ai.total_length).unwrap() - 4;
}, },
ChunkType::TrackList => { ChunkType::TrackList => {
info!("TrackList"); info!("TrackList");
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
u = usize::try_from(header.total_length).unwrap() - 4;
}, },
ChunkType::TrackItem => { ChunkType::TrackItem => {
let ti = rkyv::access::<ArchivedTrackItem, Error>(&data[i..i+std::mem::size_of::<TrackItem>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
info!("val: {:?}", ti); info!("val: {:?}", rkyv::access::<ArchivedTrackItem, Error>(&data[i..i+u]).unwrap());
u = usize::try_from(ti.total_length).unwrap() - 4;
}, },
ChunkType::StringTypes => { ChunkType::StringTypes => {
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap(); u = usize::try_from(header.children_count).unwrap() - 12;
u = usize::try_from(header.header_length).unwrap() - 4; let header_offset: usize = (header.end_of_chunk + 4) as usize;
let header_offset: usize = (header.total_length + 4) as usize; let str_end: usize = (header.children_count - 12) as usize;
let str_end: usize = (header.header_length - 4) as usize;
let entry = rkyv::access::<ArchivedEntry, Error>(&data[i..i+28]).unwrap(); let entry = rkyv::access::<ArchivedEntry, Error>(&data[i..i+28]).unwrap();
info!("val: {:?}", &entry); info!("val: {:?}", &entry);
let mut bytes = Vec::new(); if entry.entry_type <= 15 {
let mut bytes = Vec::new();
let mut h = i+header_offset; let mut h = i+header_offset;
while h < i+str_end { while h < i+str_end {
if data[h] != 0 { if data[h] != 0 {
bytes.push(data[h]); 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 => { ChunkType::PlaylistList => {
let header = rkyv::access::<ArchivedHeader, Error>(&data[i..i+std::mem::size_of::<Header>()]).unwrap(); info!("Playlists count: {}", header.children_count);
info!("Playlists count: {}", header.header_length); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
u = usize::try_from(header.total_length).unwrap() - 4;
}, },
ChunkType::Playlist => { ChunkType::Playlist => {
let playlist = rkyv::access::<ArchivedPlaylist, Error>(&data[i..i+std::mem::size_of::<Playlist>()]).unwrap(); u = usize::try_from(header.end_of_chunk).unwrap() - 12;
let playlist = rkyv::access::<ArchivedPlaylist, Error>(&data[i..i+u]).unwrap();
info!("playlist: {:?}", playlist); info!("playlist: {:?}", playlist);
u = usize::try_from(playlist.total_length).unwrap() - 4;
}, },
_ => return _ => { u = 1; }
} }
i += u; i += u;
chunk_type = None; chunk_header = None;
ChunkState::Header ChunkState::Header
} }
} }

7
src/xml.rs Normal file
View File

@ -0,0 +1,7 @@
struct Database {
}
trait Child {
}