mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-09 06:18:46 +08:00
优化 ArchiveContent 接口,改为使用 MemReader 处理数据,提升内存管理效率
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::ext::io::*;
|
||||
use crate::types::*;
|
||||
use anyhow::Result;
|
||||
use std::io::{Read, Seek, Write};
|
||||
@@ -109,15 +110,22 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ArchiveContent {
|
||||
pub trait ArchiveContent: Read {
|
||||
fn name(&self) -> &str;
|
||||
fn data(&self) -> &[u8];
|
||||
fn is_script(&self) -> bool {
|
||||
self.script_type().is_some()
|
||||
}
|
||||
fn script_type(&self) -> Option<&ScriptType> {
|
||||
None
|
||||
}
|
||||
fn data(&mut self) -> Result<Vec<u8>> {
|
||||
let mut data = Vec::new();
|
||||
self.read_to_end(&mut data)?;
|
||||
Ok(data)
|
||||
}
|
||||
fn to_data<'a>(&'a mut self) -> Result<Box<dyn ReadSeek + 'a>> {
|
||||
Ok(Box::new(MemReader::new(self.data()?)))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Script: std::fmt::Debug {
|
||||
|
||||
@@ -123,7 +123,13 @@ struct BinEntry {
|
||||
|
||||
struct Entry {
|
||||
name: String,
|
||||
data: Vec<u8>,
|
||||
data: MemReader,
|
||||
}
|
||||
|
||||
impl Read for Entry {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
self.data.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl ArchiveContent for Entry {
|
||||
@@ -131,12 +137,22 @@ impl ArchiveContent for Entry {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn data(&self) -> &[u8] {
|
||||
&self.data
|
||||
fn script_type(&self) -> Option<&ScriptType> {
|
||||
if self.data.data.starts_with(b"ESCR1_00") {
|
||||
Some(&ScriptType::Escude)
|
||||
} else if self.data.data.starts_with(b"LIST") {
|
||||
Some(&ScriptType::EscudeList)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_script(&self) -> bool {
|
||||
self.data.starts_with(b"ESCR1_00") || self.data.starts_with(b"LIST")
|
||||
fn data(&mut self) -> Result<Vec<u8>> {
|
||||
Ok(self.data.data.clone())
|
||||
}
|
||||
|
||||
fn to_data<'a>(&'a mut self) -> Result<Box<dyn ReadSeek + 'a>> {
|
||||
Ok(Box::new(&mut self.data))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +304,10 @@ impl<'a, T: Iterator<Item = &'a BinEntry>, R: Read + Seek> Iterator
|
||||
Err(e) => return Some(Err(e)),
|
||||
};
|
||||
}
|
||||
Some(Ok(Box::new(Entry { name, data })))
|
||||
Some(Ok(Box::new(Entry {
|
||||
name,
|
||||
data: MemReader::new(data),
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,13 @@ struct CustomHeader {
|
||||
|
||||
struct Entry {
|
||||
name: String,
|
||||
data: Vec<u8>,
|
||||
data: MemReader,
|
||||
}
|
||||
|
||||
impl Read for Entry {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
self.data.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl ArchiveContent for Entry {
|
||||
@@ -142,13 +148,17 @@ impl ArchiveContent for Entry {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn data(&self) -> &[u8] {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn script_type(&self) -> Option<&ScriptType> {
|
||||
Some(&ScriptType::YaneuraoItufuru)
|
||||
}
|
||||
|
||||
fn data(&mut self) -> Result<Vec<u8>> {
|
||||
Ok(self.data.data.clone())
|
||||
}
|
||||
|
||||
fn to_data<'a>(&'a mut self) -> Result<Box<dyn ReadSeek + 'a>> {
|
||||
Ok(Box::new(&mut self.data))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -250,7 +260,10 @@ impl<'a, T: Iterator<Item = &'a CustomHeader>, R: Read + Seek> Iterator
|
||||
) {
|
||||
Ok(data) => {
|
||||
let name = entry.file_name.clone();
|
||||
Some(Ok(Box::new(Entry { name, data })))
|
||||
Some(Ok(Box::new(Entry {
|
||||
name,
|
||||
data: MemReader::new(data),
|
||||
})))
|
||||
}
|
||||
Err(e) => Some(Err(anyhow::anyhow!(
|
||||
"Failed to read file {}: {}",
|
||||
|
||||
Reference in New Issue
Block a user