modified: outdb
modified: src/deserializer.rs modified: src/main.rs modified: src/objects.rs modified: src/serializer.rs modified: src/xobjects.rs
This commit is contained in:
parent
12db938009
commit
564d894846
@ -37,16 +37,17 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let ds: DataSet = bincode::deserialize(&data[i..i+u]).unwrap();
|
||||
info!("DataSet: {:?}", ds);
|
||||
last_type = ds.data_type;
|
||||
xdb.children.push(XDataSet { header: header, data: ds.clone(), child: match ds.data_type {
|
||||
3 => XSomeList::Playlists(Vec::new()), // Playlist List
|
||||
4 => XSomeList::AlbumList(Vec::new()), // Album List
|
||||
_ => XSomeList::TrackList(Vec::new()) // Track List (1)
|
||||
1 => XSomeList::TrackList(Vec::new()), // Track List
|
||||
_ => XSomeList::Playlists(Vec::new()) // Playlist List 3
|
||||
}});
|
||||
},
|
||||
ChunkType::AlbumList => {
|
||||
info!("AlbumList");
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
last_type = 4;
|
||||
//last_type = 4;
|
||||
},
|
||||
ChunkType::AlbumItem => {
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
@ -60,7 +61,7 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
ChunkType::TrackList => {
|
||||
info!("TrackList");
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
last_type = 1;
|
||||
//last_type = 1;
|
||||
},
|
||||
ChunkType::TrackItem => {
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
@ -71,9 +72,12 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
}
|
||||
},
|
||||
ChunkType::SongReference => {
|
||||
u = usize::try_from(header.children_count).unwrap() - 12;
|
||||
let item: PlaylistItem = bincode::deserialize(&data[i..i+24]).unwrap();
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let item: PlaylistItem = bincode::deserialize(&data[i..i+76]).unwrap();
|
||||
info!("PlaylistItem: {:?}", item);
|
||||
if let XSomeList::Playlists(playlists) = &mut xdb.find_dataset(last_type).child { // 3
|
||||
playlists.last_mut().unwrap().elems.push((item, Vec::new()));
|
||||
}
|
||||
},
|
||||
ChunkType::StringTypes => {
|
||||
u = usize::try_from(header.children_count).unwrap() - 12;
|
||||
@ -100,7 +104,11 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
albums.last_mut().unwrap().args.push(XArgument{ arg_type: entry_type, val: g});
|
||||
},
|
||||
XSomeList::Playlists(playlists) => {
|
||||
if playlists.last().unwrap().elems.is_empty() {
|
||||
playlists.last_mut().unwrap().args.push(XPlArgument::String(XArgument{ arg_type: entry_type, val: g}));
|
||||
} else {
|
||||
playlists.last_mut().unwrap().elems.last_mut().unwrap().1.push(XPlArgument::String(XArgument{ arg_type: entry_type, val: g}));
|
||||
}
|
||||
},
|
||||
XSomeList::TrackList(tracks) => {
|
||||
tracks.last_mut().unwrap().args.push(XArgument{ arg_type: entry_type, val: g});
|
||||
@ -109,24 +117,28 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
},
|
||||
52 => {
|
||||
let entry: PlaylistIndexEntry = bincode::deserialize(&data[i..i+60]).unwrap();
|
||||
info!("valPl: {:?}", &entry);
|
||||
//info!("valPl: {:?}", &entry);
|
||||
let mut h = i+60;
|
||||
let mut v = Vec::new();
|
||||
while h < i+60+((4*entry.count) as usize) {
|
||||
v.push(u32::from_le_bytes(data[h..h+4].try_into().unwrap()));
|
||||
h += 4;
|
||||
}
|
||||
info!("Indexes: {:?}", v);
|
||||
//info!("Indexes: {:?}", v);
|
||||
match &mut xdb.find_dataset(last_type).child {
|
||||
XSomeList::Playlists(playlists) => {
|
||||
if playlists.last().unwrap().elems.is_empty() {
|
||||
playlists.last_mut().unwrap().args.push(XPlArgument::IndexEntry(XPlaylistIndexEntry{data: entry, v}));
|
||||
} else {
|
||||
playlists.last_mut().unwrap().elems.last_mut().unwrap().1.push(XPlArgument::IndexEntry(XPlaylistIndexEntry{data: entry, v}));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
53 => {
|
||||
let entry: LetterJumpEntry = bincode::deserialize(&data[i..i+28]).unwrap();
|
||||
info!("valJT: {:?}", &entry);
|
||||
//info!("valJT: {:?}", &entry);
|
||||
let mut h = i+28;
|
||||
let mut v: Vec<JumpTable> = Vec::new();
|
||||
while h < i+28+((12*entry.count) as usize) {
|
||||
@ -136,7 +148,11 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
info!("Indexes: {:?}", v);
|
||||
match &mut xdb.find_dataset(last_type).child {
|
||||
XSomeList::Playlists(playlists) => {
|
||||
if playlists.last().unwrap().elems.is_empty() {
|
||||
playlists.last_mut().unwrap().args.push(XPlArgument::LetterJumpEntry(XLetterJump{ data: entry, v }));
|
||||
} else {
|
||||
playlists.last_mut().unwrap().elems.last_mut().unwrap().1.push(XPlArgument::LetterJumpEntry(XLetterJump{ data: entry, v }));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -145,7 +161,11 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
info!("Entry #100,102 fetched");
|
||||
match &mut xdb.find_dataset(last_type).child {
|
||||
XSomeList::Playlists(playlists) => {
|
||||
if playlists.last().unwrap().elems.is_empty() {
|
||||
playlists.last_mut().unwrap().args.push(XPlArgument::RawArgument(data[i-12..i+(header.children_count as usize)-12].to_vec()));
|
||||
} else {
|
||||
playlists.last_mut().unwrap().elems.last_mut().unwrap().1.push(XPlArgument::RawArgument(data[i-12..i+(header.children_count as usize)-12].to_vec()));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -156,14 +176,14 @@ pub fn parse_bytes(data: &[u8]) -> XDatabase {
|
||||
ChunkType::PlaylistList => {
|
||||
info!("Playlists count: {}", header.children_count);
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
last_type = 3;
|
||||
//last_type = 3;
|
||||
},
|
||||
ChunkType::Playlist => {
|
||||
u = usize::try_from(header.end_of_chunk).unwrap() - 12;
|
||||
let playlist: Playlist = bincode::deserialize(&data[i..i+u]).unwrap();
|
||||
info!("playlist: {:?}", playlist);
|
||||
if let XSomeList::Playlists(playlists) = &mut xdb.find_dataset(3).child {
|
||||
playlists.push(XPlaylist {header: header, data: playlist,args: Vec::new()});
|
||||
if let XSomeList::Playlists(playlists) = &mut xdb.find_dataset(last_type).child { // 3
|
||||
playlists.push(XPlaylist {header: header, data: playlist,args: Vec::new(), elems: Vec::new()});
|
||||
}
|
||||
},
|
||||
_ => { u = 1; }
|
||||
|
@ -26,7 +26,7 @@ fn main() {
|
||||
Ok(n) => {
|
||||
let data = &buf[..n];
|
||||
let xdb = deserializer::parse_bytes(data);
|
||||
info!("XDB: {:?}", xdb);
|
||||
//info!("XDB: {:?}", xdb);
|
||||
let mut op = File::create("outdb").unwrap();
|
||||
info!("Write res: {:?}", op.write(&serializer::to_bytes(xdb)));
|
||||
},
|
||||
|
@ -221,5 +221,7 @@ pub struct PlaylistItem {
|
||||
group_id: u32,
|
||||
track_id: u32,
|
||||
timestamp: u32,
|
||||
podcast_grouping_reference: u32
|
||||
podcast_grouping_reference: u32,
|
||||
unk: [u8; 30],
|
||||
unk1: [u8; 10]
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
use crate::{objects::{ChunkHeader, ChunkType, StringEntry}, xobjects::{XArgument, XDatabase, XPlArgument, XSomeList}};
|
||||
use log::info;
|
||||
|
||||
use crate::{objects::{ChunkHeader, ChunkType, PlaylistItem, StringEntry}, xobjects::{XArgument, XDatabase, XLetterJump, XPlArgument, XPlaylistIndexEntry, XSomeList}};
|
||||
|
||||
|
||||
fn string_to_ipod16(str: &String) -> Vec<u8> {
|
||||
@ -45,19 +47,7 @@ fn generate_zeroes(cnt: u32) -> Vec<u8> {
|
||||
v
|
||||
}
|
||||
|
||||
pub fn to_bytes(xdb: XDatabase) -> Vec<u8> {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
for i in 0..xdb.children.len() {
|
||||
let data_set = xdb.children.get(i).unwrap();
|
||||
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();
|
||||
|
||||
let mut args: Vec<u8> = playlist.args.iter()
|
||||
.map(|arg| match arg {
|
||||
XPlArgument::String(xarg) => {
|
||||
fn serialize_string_arg(xarg: &XArgument) -> Vec<u8> {
|
||||
let s = string_to_ipod16(&xarg.val);
|
||||
let mut b = bincode::serialize(&StringEntry {
|
||||
entry_type: xarg.arg_type,
|
||||
@ -75,8 +65,9 @@ pub fn to_bytes(xdb: XDatabase) -> Vec<u8> {
|
||||
}).unwrap();
|
||||
b = [h, b, s].concat();
|
||||
return b;
|
||||
},
|
||||
XPlArgument::IndexEntry(xpl) => {
|
||||
}
|
||||
|
||||
fn serialize_index_entry(xpl: &XPlaylistIndexEntry) -> Vec<u8> {
|
||||
let mut b = bincode::serialize(&xpl.data).unwrap();
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
for i in xpl.v.iter() {
|
||||
@ -89,8 +80,9 @@ pub fn to_bytes(xdb: XDatabase) -> Vec<u8> {
|
||||
}).unwrap();
|
||||
b = [h, b, v].concat();
|
||||
return b;
|
||||
},
|
||||
XPlArgument::LetterJumpEntry(xjump) => {
|
||||
}
|
||||
|
||||
fn serialize_x_letter(xjump: &XLetterJump) -> Vec<u8> {
|
||||
let mut b = bincode::serialize(&xjump.data).unwrap();
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
for i in xjump.v.iter() {
|
||||
@ -103,13 +95,38 @@ pub fn to_bytes(xdb: XDatabase) -> Vec<u8> {
|
||||
}).unwrap();
|
||||
b = [h, b, v].concat();
|
||||
return b;
|
||||
},
|
||||
XPlArgument::RawArgument(raw_arg) => {
|
||||
raw_arg.to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_arguments(pl: &Vec<XPlArgument>) -> Vec<u8> {
|
||||
pl.iter()
|
||||
.map(|arg| match arg {
|
||||
XPlArgument::String(xarg) => serialize_string_arg(xarg),
|
||||
XPlArgument::IndexEntry(xpl) => serialize_index_entry(xpl),
|
||||
XPlArgument::LetterJumpEntry(xjump) => serialize_x_letter(xjump),
|
||||
XPlArgument::RawArgument(raw_arg) => raw_arg.to_vec()
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn to_bytes(xdb: XDatabase) -> Vec<u8> {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
for i in 0..xdb.children.len() {
|
||||
let data_set = xdb.children.get(i).unwrap();
|
||||
info!("Serializer: {:?}", data_set);
|
||||
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();
|
||||
|
||||
let mut args: Vec<u8> = serialize_arguments(&playlist.args);
|
||||
for (playlist_item, xargs) in playlist.elems.iter() {
|
||||
let mut a = serialize_arguments(xargs);
|
||||
args.append(&mut generate_header(ChunkType::SongReference, 64,a.len()));
|
||||
args.append(&mut bincode::serialize(playlist_item).unwrap());
|
||||
args.append(&mut a);
|
||||
}
|
||||
|
||||
pl_bytes.append(&mut generate_header(ChunkType::Playlist, 36,args.len()));
|
||||
pl_bytes.append(&mut bincode::serialize(&playlist.data).unwrap());
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::objects::{JumpTable, LetterJumpEntry, PlaylistIndexEntry, ChunkHeader, Database, DataSet, TrackItem, AlbumItem, Playlist};
|
||||
use crate::objects::{AlbumItem, ChunkHeader, DataSet, Database, JumpTable, LetterJumpEntry, Playlist, PlaylistIndexEntry, PlaylistItem, TrackItem};
|
||||
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
@ -33,7 +33,8 @@ pub struct XAlbumItem {
|
||||
pub struct XPlaylist {
|
||||
pub header: ChunkHeader,
|
||||
pub data: Playlist,
|
||||
pub args: Vec<XPlArgument>
|
||||
pub args: Vec<XPlArgument>,
|
||||
pub elems: Vec<(PlaylistItem, Vec<XPlArgument>)>
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
@ -69,26 +70,6 @@ pub enum XSomeList {
|
||||
AlbumList(Vec<XAlbumItem>)
|
||||
}
|
||||
|
||||
impl XSomeList {
|
||||
fn push_album(&mut self, album: XAlbumItem ) {
|
||||
if let XSomeList::AlbumList(albums) = self {
|
||||
albums.push(album);
|
||||
}
|
||||
}
|
||||
|
||||
fn push_track(&mut self, track: XTrackItem ) {
|
||||
if let XSomeList::TrackList(tracks) = self {
|
||||
tracks.push(track);
|
||||
}
|
||||
}
|
||||
|
||||
fn push_playlist(&mut self, playlist: XPlaylist ) {
|
||||
if let XSomeList::Playlists(playlists) = self {
|
||||
playlists.push(playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl XDatabase {
|
||||
pub fn find_dataset(&mut self, data_type: u32) -> &mut XDataSet {
|
||||
self.children.iter_mut().find(|d| d.data.data_type == data_type).unwrap()
|
||||
|
Loading…
x
Reference in New Issue
Block a user