diff --git a/src/main.rs b/src/lib.rs similarity index 82% rename from src/main.rs rename to src/lib.rs index 636f298..21d1600 100644 --- a/src/main.rs +++ b/src/lib.rs @@ -36,6 +36,23 @@ impl From<[u8; 4]> for ChunkType { } } +impl From for [u8; 4] { + fn from(value: ChunkType) -> Self { + match value { + ChunkType::Database => [0x6D, 0x68, 0x62, 0x64], + ChunkType::DataSet => [0x6D, 0x68, 0x73, 0x64], + ChunkType::AlbumList => [0x6D, 0x68, 0x69, 0x61], + ChunkType::AlbumItem => [0x6D, 0x68, 0x6C, 0x61], + ChunkType::TrackList => [0x6D, 0x68, 0x6C, 0x74], + ChunkType::TrackItem => [0x6D, 0x68, 0x69, 0x74], + ChunkType::StringTypes => [0x6D, 0x68, 0x6F, 0x64], + ChunkType::PlaylistList => [0x6D, 0x68, 0x6C, 0x70], + ChunkType::Playlist => [0x6D, 0x68, 0x79, 0x70], + ChunkType::Unknown => [0x00, 0x00, 0x00, 0x00] + } + } +} + #[derive(Serialize, Deserialize, PartialEq, Debug)] struct ChunkHeader { chunk_type: [u8; 4], @@ -355,6 +372,64 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase { xdb } +fn string_to_ipod16(str: &String) -> Vec { + str.as_bytes().iter().map(|b| [*b, 0x0]).flatten().collect() +} + +fn x_args_to_bytes(args: &Vec) -> Vec { + args.iter() + .filter(|arg| arg.arg_type <= 15) + .map(|arg| { + let s = string_to_ipod16(&arg.val); + let mut b = bincode::serialize(&StringEntry { + entry_type: arg.arg_type, + unk1: 0, + unk2: 0, + position: 1, + length: s.len() as u32, + unknown: 0, + unk4: 0 + }).unwrap(); + b = [b, s].concat(); + return b; + }) + .flatten() + .collect() +} + +fn to_bytes(xdb: XDatabase) -> Vec { + let mut bytes: Vec = Vec::new(); + 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.data).unwrap()].concat(); + match &data_set.child { + XSomeList::Playlists(playlists) => { + for u in 0..playlists.len() { + let playlist = playlists.get(u).unwrap(); + bytes = [bytes, bincode::serialize(&playlist.data).unwrap()].concat(); + bytes = [bytes, x_args_to_bytes(&playlist.args)].concat(); + } + }, + XSomeList::AlbumList(albums) => { + for u in 0..albums.len() { + let album = albums.get(u).unwrap(); + bytes = [bytes, bincode::serialize(&album.data).unwrap()].concat(); + bytes = [bytes, x_args_to_bytes(&album.args)].concat(); + } + }, + XSomeList::TrackList(tracks) => { + for u in 0..tracks.len() { + let track = tracks.get(u).unwrap(); + bytes = [bytes, bincode::serialize(&track.data).unwrap()].concat(); + bytes = [bytes, x_args_to_bytes(&track.args)].concat(); + } + } + } + } + bytes +} + /*fn main() { // Initialize the logger with 'info' as the default level