diff --git a/maple-rs/src/db.rs b/maple-rs/src/db.rs index 2123bde..baff311 100644 --- a/maple-rs/src/db.rs +++ b/maple-rs/src/db.rs @@ -57,74 +57,70 @@ pub struct Database { const PAGE_SIZE: u16 = 4096; impl Database { - pub fn export(self, path: &Path) -> Result<(), PageError> { - let pages = Table::from_rows(PageType::Tracks, 1, PAGE_SIZE, self.tracks.values().cloned().map(Row::Track))?; - println!("{:?}", pages.len()); - println!("{:?}", pages.last()); - Ok(()) - } - // pub fn export(self, path: &Path) -> std::io::Result<()> { - // // 1) Reserve header page - // let mut f = File::create(path)?; - // f.write_all(&vec![0u8; PAGE_SIZE as usize])?; - - // // 2) Emit tables linearly, collect table metadata - // let mut next_page_index: u32 = 1; - - // // ok now we're getting somewhere - // // smash rows into row_groups of 16 - // // try to write those into a page until it is full - // // yield pages until all the rows are in - // // set the indices - // // 420 blaze it - - // let (tracks_first, tracks_last) = - // Self::write_table(&mut f, PageType::Tracks, next_page_index, self.tracks.values().cloned().map(Row::Track))?; - // next_page_index = tracks_last + 1; - - // let (tree_first, tree_last) = - // Self::write_table(&mut f, PageType::PlaylistTree, next_page_index, self.nodes.values().cloned().map(Row::PlaylistTreeNode))?; - // next_page_index = tree_last + 1; - - // let plist_entries = self.entries.iter().flat_map(|(_pid, vec)| { - // // ensure contiguous entry_index - // let mut v = vec.clone(); - // v.sort_by_key(|e| e.entry_index); - // v.into_iter().map(Row::PlaylistEntry) - // }); - // let (entries_first, entries_last) = - // Self::write_table(&mut f, PageType::PlaylistEntries, next_page_index, plist_entries)?; - // next_page_index = entries_last + 1; - - // let (art_first, art_last) = - // Self::write_table(&mut f, PageType::Artwork, next_page_index, self.artwork.values().cloned().map(Row::Artwork))?; - // next_page_index = art_last + 1; - - // // 3) Build header and back-patch at page 0 - // let header = Header { - // // fill other required fields in your crate - // sequence: 1, // or previous+1 - // next_unused_page: PageIndex(next_page_index), - // tables: vec![ - // Table { page_type: PageType::Tracks, first_page: PageIndex(tracks_first), last_page: PageIndex(tracks_last), empty_candidate: 0, /* … */ }, - // Table { page_type: PageType::PlaylistTree, first_page: PageIndex(tree_first), last_page: PageIndex(tree_last), empty_candidate: 0, /* … */ }, - // Table { page_type: PageType::PlaylistEntries, first_page: PageIndex(entries_first), last_page: PageIndex(entries_last), empty_candidate: 0, /* … */ }, - // Table { page_type: PageType::Artwork, first_page: PageIndex(art_first), last_page: PageIndex(art_last), empty_candidate: 0, /* … */ }, - // ], - // ..Default::default() - // }; - - // // Write header at offset 0 and pad to one page - // f.seek(SeekFrom::Start(0))?; - // header.write(&mut f); - // // pad residual of page 0 if BinWrite didn’t fill it: - // let pos = f.stream_position()?; - // if pos < PAGE_SIZE as u64 { - // f.write_all(&vec![0u8; (PAGE_SIZE as u64 - pos) as usize])?; - // } + // pub fn export(self, path: &Path) -> Result<(), PageError> { + // let table = Table::from_rows(PageType::Tracks, 1, PAGE_SIZE, self.tracks.values().cloned().map(Row::Track))?; + // println!("{:?}", table); // Ok(()) // } + pub fn export(self, path: &Path) -> std::io::Result<()> { + // 1) Reserve header page + let mut f = File::create(path)?; + f.write_all(&vec![0u8; PAGE_SIZE as usize])?; + + let (table, pages) = Table::from_rows(PageType::Tracks, 1, PAGE_SIZE, self.tracks.values().cloned().take(1).map(Row::Track)).unwrap(); + + println!("{:?}", table); + println!("{:?}", pages); + table.write_le(&mut f).unwrap(); + pages.write_le_args(&mut f, (PAGE_SIZE.into(),)).unwrap(); + + // page is somehow getting zeroed when ... writing? reading?? + // validate it by writing and reading it back + + // let (tree_first, tree_last) = + // Self::write_table(&mut f, PageType::PlaylistTree, next_page_index, self.nodes.values().cloned().map(Row::PlaylistTreeNode))?; + // next_page_index = tree_last + 1; + + // let plist_entries = self.entries.iter().flat_map(|(_pid, vec)| { + // // ensure contiguous entry_index + // let mut v = vec.clone(); + // v.sort_by_key(|e| e.entry_index); + // v.into_iter().map(Row::PlaylistEntry) + // }); + // let (entries_first, entries_last) = + // Self::write_table(&mut f, PageType::PlaylistEntries, next_page_index, plist_entries)?; + // next_page_index = entries_last + 1; + + // let (art_first, art_last) = + // Self::write_table(&mut f, PageType::Artwork, next_page_index, self.artwork.values().cloned().map(Row::Artwork))?; + // next_page_index = art_last + 1; + + // 3) Build header and back-patch at page 0 + let header = Header { + // fill other required fields in your crate + sequence: 0, // or previous+1 + next_unused_page: PageIndex(pages.len() as u32 + 1), + tables: vec![ + table, + // Table { page_type: PageType::PlaylistTree, first_page: PageIndex(tree_first), last_page: PageIndex(tree_last), empty_candidate: 0, /* … */ }, + // Table { page_type: PageType::PlaylistEntries, first_page: PageIndex(entries_first), last_page: PageIndex(entries_last), empty_candidate: 0, /* … */ }, + // Table { page_type: PageType::Artwork, first_page: PageIndex(art_first), last_page: PageIndex(art_last), empty_candidate: 0, /* … */ }, + ], + ..Default::default() + }; + + // Write header at offset 0 and pad to one page + f.seek(SeekFrom::Start(0))?; + header.write_le(&mut f).unwrap(); + // pad residual of page 0 if BinWrite didn’t fill it: + let pos = f.stream_position()?; + if pos < PAGE_SIZE as u64 { + f.write_all(&vec![0u8; (PAGE_SIZE as u64 - pos) as usize])?; + } + Ok(()) + } + // fn write_table( // f: &mut File, // page_type: PageType, @@ -198,7 +194,7 @@ impl Database { let mut entries: BTreeMap> = BTreeMap::new(); for table in &header.tables { - let pages = header.read_pages(&mut f, Endian::NATIVE, (&table.first_page, &table.last_page))?; + let pages = header.read_pages(&mut f, Endian::Little, (&table.first_page, &table.last_page))?; for page in pages { for rg in page.row_groups { diff --git a/maple-rs/src/main.rs b/maple-rs/src/main.rs index be76add..d36a239 100644 --- a/maple-rs/src/main.rs +++ b/maple-rs/src/main.rs @@ -26,7 +26,11 @@ fn main() -> Result<(), PageError> { println!("tables: {:?}", db.header); println!("tables: {:?}", db.header.tables); - db.export(&Path::new("./data/output.pdb"))?; + let output = Path::new("./data/output.pdb"); + db.export(&output).unwrap(); + + // let db = Database::load_from_pdb("./data/output.pdb").unwrap(); + // println!("{:?}", db); // for n in db.nodes { // println!("{:?}", n);