Name macro

This commit is contained in:
widberg 2026-04-14 14:15:31 -04:00
parent 5a5eb49303
commit b125d18a42
24 changed files with 885 additions and 764 deletions

11
Cargo.lock generated
View file

@ -153,7 +153,6 @@ dependencies = [
"serde",
"serde_context",
"serde_json",
"string-interner",
]
[[package]]
@ -1092,16 +1091,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "string-interner"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23de088478b31c349c9ba67816fa55d9355232d63c3afea8bf513e31f0f1d2c0"
dependencies = [
"hashbrown",
"serde",
]
[[package]]
name = "strsim"
version = "0.11.1"

View file

@ -37,9 +37,8 @@ pub fn extract_cps(
in_names: &Vec<PathBuf>,
endian: &LzEndian,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let name_context = NameContext::new(NameType::BlackSheep32);
let endian: Endian = (*endian).into();
name_context.set_name_type(NameType::BlackSheep32);
if in_names.is_empty() {
read_default_cps_names(&name_context)?;
} else {
@ -90,9 +89,8 @@ pub fn create_cps(
endian: &LzEndian,
unencrypted: &bool,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let name_context = NameContext::new(NameType::BlackSheep32);
let endian: Endian = (*endian).into();
name_context.set_name_type(NameType::BlackSheep32);
let mut cps = Cps::default();
let directory_cwd = directory.join("System");
read_files_into_cps_recursively(&mut cps, directory, &directory_cwd)?;

View file

@ -7,7 +7,7 @@ use bff::bigfile::BigFile;
use bff::bigfile::platforms::Platform;
use bff::bigfile::resource::{BffClass, Resource};
use bff::bigfile::versions::Version;
use bff::names::NameContext;
use bff::names::{NameContext, NameType};
use bff::traits::{Artifact, Import, TryIntoVersionPlatform};
use indicatif::{ProgressBar, ProgressStyle};
use rayon::iter::{ParallelBridge, ParallelIterator};
@ -15,6 +15,24 @@ use rayon::iter::{ParallelBridge, ParallelIterator};
use crate::error::BffCliResult;
use crate::extract::write_names;
fn validate_version_override_name_type(
version_override: &Option<Version>,
expected_name_type: NameType,
) -> BffCliResult<()> {
if let Some(version_override) = version_override {
let override_name_type: NameType = version_override.try_into()?;
if override_name_type != expected_name_type {
return Err(std::io::Error::other(format!(
"`--version-override` implies NameType {:?}, but context requires {:?}",
override_name_type, expected_name_type
))
.into());
}
}
Ok(())
}
#[allow(clippy::too_many_arguments)]
pub fn create(
directory: &Path,
@ -25,10 +43,14 @@ pub fn create(
version_to_write: &Option<Version>,
tag: &Option<String>,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message("Reading manifest");
let manifest_path = directory.join("manifest.json");
let manifest_name_type = bff::names::json::probe_name_type_from_manifest_reader(
BufReader::new(File::open(&manifest_path)?),
)?;
validate_version_override_name_type(version_override, manifest_name_type)?;
let name_context = NameContext::new(manifest_name_type);
let manifest_reader = BufReader::new(File::open(manifest_path)?);
let manifest = bff::names::json::from_reader(manifest_reader, &name_context)?;

View file

@ -7,12 +7,30 @@ use bff::BufReader;
use bff::bigfile::platforms::Platform;
use bff::bigfile::resource::{BffClass, Resource};
use bff::bigfile::versions::Version;
use bff::names::NameContext;
use bff::names::{NameContext, NameType};
use bff::traits::{Artifact, Import, TryIntoVersionPlatform};
use crate::error::BffCliResult;
use crate::extract::write_names;
fn validate_version_override_name_type(
version_override: &Option<Version>,
expected_name_type: NameType,
) -> BffCliResult<()> {
if let Some(version_override) = version_override {
let override_name_type: NameType = version_override.try_into()?;
if override_name_type != expected_name_type {
return Err(std::io::Error::other(format!(
"`--version-override` implies NameType {:?}, but context requires {:?}",
override_name_type, expected_name_type
))
.into());
}
}
Ok(())
}
pub fn create_resource(
directory: &Path,
resource_path: &Path,
@ -20,8 +38,12 @@ pub fn create_resource(
platform_override: &Option<Platform>,
version_override: &Option<Version>,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let resource_serialized_path = directory.join("resource.json");
let name_type = bff::names::json::probe_name_type_from_bff_class_reader(BufReader::new(
File::open(&resource_serialized_path)?,
))?;
validate_version_override_name_type(version_override, name_type)?;
let name_context = NameContext::new(name_type);
let resource_serialized_reader = BufReader::new(File::open(&resource_serialized_path)?);
let mut bff_class: BffClass =
bff::names::json::from_reader(resource_serialized_reader, &name_context)?;

View file

@ -9,7 +9,7 @@ use bff::bigfile::resource::Resource;
use bff::names::NameContext;
use crate::error::BffCliResult;
use crate::extract::{read_bigfile, read_bigfile_names};
use crate::extract::{probe_bigfile_name_context, read_bigfile, read_bigfile_names};
struct ResolvedResource<'a> {
link_name: Option<String>,
@ -27,7 +27,7 @@ fn load_bigfile(
bigfile_path: &Path,
name_path: &Option<PathBuf>,
) -> BffCliResult<(BigFile, NameContext)> {
let name_context = NameContext::default();
let name_context = probe_bigfile_name_context(bigfile_path, &None, &None)?;
read_bigfile_names(bigfile_path, &name_context)?;
if let Some(name_path) = name_path {
read_name_file(name_path, &name_context)?;

View file

@ -83,6 +83,23 @@ pub fn read_bigfile(
)?)
}
pub fn probe_bigfile_name_context(
bigfile_path: &Path,
platform_override: &Option<Platform>,
version_override: &Option<Version>,
) -> BffCliResult<NameContext> {
let platform = platform_override.unwrap_or_else(|| {
bigfile_path
.extension()
.and_then(|e| e.try_into().ok())
.unwrap_or(Platform::PC)
});
let f = File::open(bigfile_path)?;
let mut reader = BufReader::new(f);
let name_type = BigFile::probe_name_type_platform(&mut reader, platform, version_override)?;
Ok(NameContext::new(name_type))
}
const INVALID_PATH_CHARS: [u8; 41] = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 34, 42, 47, 58, 60, 62, 63, 92, 124,
@ -192,7 +209,7 @@ pub fn extract(
export_strategy: &ExportStrategy,
rich_suffix: &String,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let name_context = probe_bigfile_name_context(bigfile_path, platform_override, version_override)?;
let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message("Reading names");
read_bigfile_names(bigfile_path, &name_context)?;

View file

@ -7,12 +7,30 @@ use bff::bigfile::platforms::Platform;
use bff::bigfile::resource::{BffClass, BffResource, BffResourceHeader};
use bff::bigfile::versions::Version;
use bff::class::Class;
use bff::names::NameContext;
use bff::names::{NameContext, NameType};
use bff::traits::{Artifact, Export, TryIntoVersionPlatform};
use crate::error::BffCliResult;
use crate::extract::read_in_names;
fn validate_version_override_name_type(
version_override: &Option<Version>,
expected_name_type: NameType,
) -> BffCliResult<()> {
if let Some(version_override) = version_override {
let override_name_type: NameType = version_override.try_into()?;
if override_name_type != expected_name_type {
return Err(std::io::Error::other(format!(
"`--version-override` implies NameType {:?}, but context requires {:?}",
override_name_type, expected_name_type
))
.into());
}
}
Ok(())
}
pub fn extract_resource(
resource_path: &Path,
directory: &Path,
@ -20,7 +38,10 @@ pub fn extract_resource(
platform_override: &Option<Platform>,
version_override: &Option<Version>,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let mut probe_reader = BufReader::new(File::open(resource_path)?);
let name_type = BffResourceHeader::probe_name_type(&mut probe_reader)?;
validate_version_override_name_type(version_override, name_type)?;
let name_context = NameContext::new(name_type);
read_in_names(in_names, &name_context)?;
let f = File::open(resource_path)?;

View file

@ -2,18 +2,17 @@ use std::fs::File;
use std::io::{self, BufWriter, Write};
use std::path::{Path, PathBuf};
use bff::names::NameContext;
use bff::petgraph::dot::{Config, Dot};
use crate::error::BffCliResult;
use crate::extract::{read_bigfile, read_bigfile_names, read_in_names};
use crate::extract::{probe_bigfile_name_context, read_bigfile, read_bigfile_names, read_in_names};
pub fn info(
bigfile_path: &Path,
in_names: &Vec<PathBuf>,
out_reference_graph: &Option<PathBuf>,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let name_context = probe_bigfile_name_context(bigfile_path, &None, &None)?;
read_bigfile_names(bigfile_path, &name_context)?;
read_in_names(in_names, &name_context)?;

View file

@ -2,6 +2,7 @@ use std::path::PathBuf;
use bff::bigfile::platforms::Platform;
use bff::bigfile::versions::Version;
use bff::names::NameType;
use clap::*;
use crc::{CrcAlgorithm, CrcFormat, CrcMode};
use crypt::CryptAlgorithm;
@ -115,6 +116,8 @@ enum Commands {
},
Names {
bigfile: Option<PathBuf>,
#[arg(long)]
name_type: Option<NameType>,
#[clap(value_enum)]
#[arg(short, long)]
wordlist: Option<Wordlist>,
@ -342,11 +345,19 @@ fn main() -> BffCliResult<()> {
} => diff::diff(old_bigfile, new_bigfile, old_names, new_names),
Commands::Names {
bigfile,
name_type,
wordlist,
in_names,
out_names,
use_reference_graph,
} => names::names(bigfile, wordlist, in_names, out_names, use_reference_graph),
} => names::names(
bigfile,
name_type,
wordlist,
in_names,
out_names,
use_reference_graph,
),
Commands::Crc {
string,
starting,

View file

@ -1,14 +1,14 @@
use std::collections::VecDeque;
use std::path::PathBuf;
use bff::names::{NameContext, WORDLIST_ANIMALS, WORDLIST_BIP39, get_forced_hash_string};
use bff::names::{NameContext, NameType, WORDLIST_ANIMALS, WORDLIST_BIP39, get_forced_hash_string};
use bff::petgraph;
use bff::petgraph::visit::{VisitMap, Visitable};
use clap::ValueEnum;
use indicatif::{ProgressBar, ProgressStyle};
use crate::error::BffCliResult;
use crate::extract::{read_bigfile, read_bigfile_names, read_in_names, write_names};
use crate::extract::{probe_bigfile_name_context, read_bigfile, read_bigfile_names, read_in_names, write_names};
#[derive(ValueEnum, Clone, Copy)]
pub enum Wordlist {
@ -19,20 +19,27 @@ pub enum Wordlist {
pub fn names(
bigfile_path: &Option<PathBuf>,
name_type: &Option<NameType>,
wordlist: &Option<Wordlist>,
in_names: &Vec<PathBuf>,
out_names: &Option<PathBuf>,
use_reference_graph: &bool,
) -> BffCliResult<()> {
let name_context = NameContext::default();
let name_context = if let Some(bigfile_path) = bigfile_path {
probe_bigfile_name_context(bigfile_path, &None, &None)?
} else {
NameContext::new(name_type.ok_or_else(|| {
std::io::Error::other(
"`--name-type` is required when `--bigfile` is not provided",
)
})?)
};
if let Some(bigfile_path) = bigfile_path {
read_bigfile_names(bigfile_path, &name_context)?;
}
read_in_names(in_names, &name_context)?;
if let Some(bigfile_path) = bigfile_path {
read_bigfile_names(bigfile_path, &name_context)?;
let bigfile = read_bigfile(bigfile_path, &None, &None, &name_context)?;
if let Some(wordlist) = wordlist {

View file

@ -1,5 +1,5 @@
use std::fs::File;
use std::io::BufReader;
use std::io::{BufReader, Seek};
use std::path::Path;
use bff::bigfile::BigFile;
@ -12,17 +12,24 @@ use bff::traits::TryYourBest;
use crate::error::BffCliResult;
pub fn try_your_best(path: &Path) -> BffCliResult<()> {
let name_context = NameContext::default();
let f = File::open(path)?;
let mut reader = BufReader::new(f);
if let Ok(bff_resource) = BffResource::read(&mut reader, &name_context) {
let report = <Class as TryYourBest<&Resource>>::report(
&bff_resource.resource,
bff_resource.header.platform,
);
println!("{}", report);
} else {
if let Ok(name_type) = bff::bigfile::resource::BffResourceHeader::probe_name_type(&mut reader) {
reader.rewind()?;
let name_context = NameContext::new(name_type);
if let Ok(bff_resource) = BffResource::read(&mut reader, &name_context) {
let report = <Class as TryYourBest<&Resource>>::report(
&bff_resource.resource,
bff_resource.header.platform,
);
println!("{}", report);
return Ok(());
}
reader.rewind()?;
}
{
let platform = path
.extension()
.and_then(|e| e.try_into().ok())

View file

@ -33,7 +33,6 @@ schemars = { version = "0.8.21", features = ["indexmap2"] }
serde = { version = "1.0", features = ["derive"] }
serde_context = "0.1.0"
serde_json = "1.0"
string-interner = "0.19.0"
[dev-dependencies]
datatest = "0.8.0"

View file

@ -1,4 +1,4 @@
use std::io::{Read, Seek, Write};
use std::io::{Read, Seek, SeekFrom, Write};
use binrw::{BinRead, BinWrite, binrw};
use schemars::JsonSchema;
@ -8,7 +8,7 @@ use super::platforms::Platform;
use super::versions::Version;
use crate::BffResult;
use crate::class::Class;
use crate::names::{Name, NameContext};
use crate::names::{Name, NameContext, NameType};
#[derive(Debug, Eq, PartialEq)]
pub enum ResourceData {
@ -49,6 +49,17 @@ pub struct BffResourceHeader {
}
impl BffResourceHeader {
pub fn name_type(&self) -> BffResult<NameType> {
(&self.version).try_into()
}
pub fn probe_name_type<R: Read + Seek>(reader: &mut R) -> BffResult<NameType> {
let start = reader.stream_position()?;
let header = Self::read(reader)?;
reader.seek(SeekFrom::Start(start))?;
header.name_type()
}
fn data_padded_size_on_disk(&self) -> u16 {
let non_data_size = 4 + 2;
let total_unpadded_size =

View file

@ -4,7 +4,7 @@ use binrw::{BinRead, BinResult, BinWrite, Endian, args, binread, parser};
use crate::bigfile::resource::ResourceData::SplitData;
use crate::lz::{lz4_decompress_body_parser, zlib_decompress_body_parser};
use crate::names::{Name, NameAsobo64};
use crate::names::Name;
#[parser(reader, endian)]
fn body_parser(
@ -77,7 +77,7 @@ impl Resource {
resource.name.write_options(writer, endian, ())?;
resource
.link_name
.unwrap_or(NameAsobo64::default().into())
.unwrap_or_default()
.write_options(writer, endian, ())?;
(link_header.len() as u32 + body.len() as u32).write_options(writer, endian, ())?;
(link_header.len() as u32).write_options(writer, endian, ())?;

View file

@ -4,7 +4,7 @@ use binrw::{BinRead, BinResult, BinWrite, Endian, args, binread, parser};
use crate::bigfile::resource::ResourceData::SplitData;
use crate::lz::lz4_decompress_body_parser;
use crate::names::{Name, NameAsobo64};
use crate::names::Name;
#[parser(reader, endian)]
pub fn body_parser(decompressed_size: u32, compressed_size: u32) -> BinResult<Vec<u8>> {
@ -64,7 +64,7 @@ impl Resource {
resource.name.write_options(writer, endian, ())?;
resource
.link_name
.unwrap_or(NameAsobo64::default().into())
.unwrap_or_default()
.write_options(writer, endian, ())?;
(link_header.len() as u32 + body.len() as u32).write_options(writer, endian, ())?;
(link_header.len() as u32).write_options(writer, endian, ())?;

View file

@ -6,10 +6,8 @@ use scanf::sscanf;
use schemars::schema::Schema;
use schemars::{JsonSchema, SchemaGenerator};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_context::context_scope;
use crate::helpers::PascalString;
use crate::names::{DeserializeNamesContext, SerializeNamesContext};
#[derive(Debug, Display, Clone, Eq, PartialEq, BinRead, BinWrite)]
pub enum Version {
@ -137,13 +135,6 @@ impl From<&str> for Version {
impl Serialize for Version {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
if let Ok(name_type) = self.try_into() {
context_scope(|cx| {
if let Ok(names_context) = cx.get::<SerializeNamesContext>() {
names_context.set_name_type(name_type);
}
});
}
serializer.serialize_str(&self.to_string())
}
}
@ -151,15 +142,7 @@ impl Serialize for Version {
impl<'de> Deserialize<'de> for Version {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let string = String::deserialize(deserializer)?;
let version: Self = string.as_str().into();
if let Ok(name_type) = (&version).try_into() {
context_scope(|cx| {
if let Ok(names_context) = cx.get::<DeserializeNamesContext>() {
names_context.set_name_type(name_type);
}
});
}
Ok(version)
Ok(string.as_str().into())
}
}

View file

@ -1,6 +1,24 @@
macro_rules! bigfiles {
($($pattern:pat => $bigfile:ident),* $(,)?) => {
impl BigFile {
pub fn probe_name_type_platform<R: std::io::Read + std::io::Seek>(
reader: &mut R,
_platform: crate::bigfile::platforms::Platform,
version_override: &Option<crate::bigfile::versions::Version>,
) -> crate::BffResult<crate::names::NameType> {
use binrw::BinRead;
let start = reader.stream_position()?;
let version: crate::bigfile::versions::Version =
crate::helpers::FixedStringNull::<256>::read_be(reader)?
.as_str()
.into();
reader.seek(std::io::SeekFrom::Start(start))?;
let version = version_override.clone().unwrap_or(version);
(&version).try_into()
}
#[allow(unused_imports)]
pub fn read_platform<R: std::io::Read + std::io::Seek>(
reader: &mut R,
@ -19,13 +37,20 @@ macro_rules! bigfiles {
.as_str()
.into();
let version = version_override.clone().unwrap_or(version);
name_context.scope(|| match (&version, platform) {
match (&version, platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
<$bigfile as BigFileIo>::read(reader, version, platform)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| <$bigfile as BigFileIo>::read(reader, version, platform))
})*
_ => Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into()),
})
}
}
#[allow(unused_imports)]
@ -53,15 +78,22 @@ macro_rules! bigfiles {
version.to_string()
};
crate::helpers::FixedStringNull::<256>::write_be(&version_string.into(), writer)?;
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
<$bigfile as BigFileIo>::write(self, writer, tag)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| <$bigfile as BigFileIo>::write(self, writer, tag))
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
#[allow(unused_imports)]
@ -78,15 +110,24 @@ macro_rules! bigfiles {
let platform = self.manifest.platform;
let endian: crate::Endian = platform.into();
let version = &self.manifest.version;
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
pub fn dump_bff_resource<W: std::io::Write + std::io::Seek>(
@ -119,15 +160,24 @@ macro_rules! bigfiles {
let platform = self.manifest.platform;
let endian: crate::Endian = platform.into();
let version = &self.manifest.version;
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
#[allow(unused_imports)]
@ -143,15 +193,24 @@ macro_rules! bigfiles {
let crate::bigfile::resource::BffResourceHeader { platform, version } =
<crate::bigfile::resource::BffResourceHeader as binrw::BinRead>::read(reader)?;
let endian: crate::Endian = platform.into();
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
}
@ -170,15 +229,24 @@ macro_rules! bigfiles {
let endian: crate::Endian = platform.into();
let resource = self;
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
#[allow(unused_imports)]
@ -202,15 +270,24 @@ macro_rules! bigfiles {
writer,
)?;
let resource = self;
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::dump_resource(resource, writer, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
#[allow(unused_imports)]
@ -225,15 +302,24 @@ macro_rules! bigfiles {
use crate::traits::BigFileIo;
let endian: crate::Endian = platform.into();
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
#[allow(unused_imports)]
@ -248,15 +334,24 @@ macro_rules! bigfiles {
let crate::bigfile::resource::BffResourceHeader { platform, version } =
<crate::bigfile::resource::BffResourceHeader as binrw::BinRead>::read(reader)?;
let endian: crate::Endian = platform.into();
name_context.scope(|| match (version.clone(), platform) {
match (version.clone(), platform) {
$($pattern => {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
if name_context.name_type() != <$bigfile as BigFileIo>::NAME_TYPE {
return Err(std::io::Error::other(format!(
"NameContext type mismatch: expected {:?}, got {:?}",
<$bigfile as BigFileIo>::NAME_TYPE,
name_context.name_type()
))
.into());
}
name_context.scope(|| {
Ok(<$bigfile as BigFileIo>::ResourceType::read_resource(reader, endian)?)
})
})*
(version, platform) => {
Err(crate::error::UnimplementedVersionPlatformError::new(version, platform).into())
}
})
}
}
}
@ -277,13 +372,12 @@ macro_rules! bigfiles {
) {
use crate::traits::BigFileIo;
let name_context = crate::names::NameContext::default();
report.total += 1;
// TODO: Probably need a way to do this without specifying a version.
$(
reader.seek(std::io::SeekFrom::Start(256)).unwrap();
report.$bigfile += {
name_context.set_name_type(<$bigfile as BigFileIo>::NAME_TYPE);
let name_context = crate::names::NameContext::new(<$bigfile as BigFileIo>::NAME_TYPE);
<bool as Into<usize>>::into(name_context.scope(|| {
<$bigfile as BigFileIo>::read(
reader,

View file

@ -20,7 +20,7 @@ macro_rules! classes {
)*
$crate::macros::classes::classes!(@emit_class_enums $($class)*);
$crate::macros::classes::classes!(@emit_try_from_name $($class)*);
$crate::macros::classes::classes!(@emit_class_name_maps $($class)*);
$crate::macros::classes::classes!(@emit_try_from_resource $($class)*);
$crate::macros::classes::classes!(@emit_try_into_resource $($class)*);
$crate::macros::classes::classes!(@emit_class_try_your_best_report $($class)*);
@ -37,23 +37,76 @@ macro_rules! classes {
$($class($crate::macros::classes::classes!(@class_ty $class)),)*
}
#[derive(serde::Serialize, Debug, serde::Deserialize, schemars::JsonSchema)]
#[derive(serde::Serialize, Debug, Clone, Copy, Eq, PartialEq, serde::Deserialize, schemars::JsonSchema)]
pub enum ClassType {
$($class,)*
}
};
(@emit_try_from_name $($class:ident)*) => {
impl TryFrom<crate::names::Name> for (ClassType, crate::names::NameStyle, crate::names::NameType) {
(@emit_class_name_maps $($class:ident)*) => {
impl ClassType {
pub fn from_name_and_type(
name: crate::names::Name,
name_type: crate::names::NameType,
) -> Option<Self> {
use std::collections::HashMap;
use std::sync::OnceLock;
fn build(
name_type: crate::names::NameType,
) -> HashMap<crate::names::Name, ClassType> {
let mut map = HashMap::new();
$(
let styled = crate::names::apply_name_style(
stringify!($class),
crate::names::name_type_style(name_type),
);
map.insert(
crate::names::hash_string_for_type(name_type, styled),
ClassType::$class,
);
)*
map
}
static ASOBO32: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
static ASOBO_ALTERNATE32: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
static KALISTO32: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
static BLACKSHEEP32: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
static ASOBO64: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
static UBISOFT64: OnceLock<HashMap<crate::names::Name, ClassType>> = OnceLock::new();
let map = match name_type {
crate::names::NameType::Asobo32 => {
ASOBO32.get_or_init(|| build(crate::names::NameType::Asobo32))
}
crate::names::NameType::AsoboAlternate32 => ASOBO_ALTERNATE32
.get_or_init(|| build(crate::names::NameType::AsoboAlternate32)),
crate::names::NameType::Kalisto32 => {
KALISTO32.get_or_init(|| build(crate::names::NameType::Kalisto32))
}
crate::names::NameType::BlackSheep32 => {
BLACKSHEEP32.get_or_init(|| build(crate::names::NameType::BlackSheep32))
}
crate::names::NameType::Asobo64 => {
ASOBO64.get_or_init(|| build(crate::names::NameType::Asobo64))
}
crate::names::NameType::Ubisoft64 => {
UBISOFT64.get_or_init(|| build(crate::names::NameType::Ubisoft64))
}
};
map.get(&name).copied()
}
}
impl TryFrom<(crate::names::Name, crate::names::NameType)> for ClassType {
type Error = ();
fn try_from(name: crate::names::Name) -> Result<(ClassType, crate::names::NameStyle, crate::names::NameType), ()> {
$(
if let Some((style, name_type)) = $crate::macros::classes::classes!(@class_name_style_type $class name) {
return Ok((ClassType::$class, style, name_type));
}
)*
Err(())
fn try_from(
(name, name_type): (crate::names::Name, crate::names::NameType),
) -> Result<ClassType, ()> {
ClassType::from_name_and_type(name, name_type).ok_or(())
}
}
};
@ -63,11 +116,14 @@ macro_rules! classes {
type Error = crate::error::Error;
fn try_from_version_platform(resource: &crate::bigfile::resource::Resource, version: crate::bigfile::versions::Version, platform: crate::bigfile::platforms::Platform) -> crate::BffResult<Class> {
$(
if $crate::macros::classes::classes!(@class_name_style_type $class resource.class_name).is_some() {
return Ok(<&crate::bigfile::resource::Resource as crate::traits::TryIntoVersionPlatform<$crate::macros::classes::classes!(@class_ty $class)>>::try_into_version_platform(resource, version, platform)?.into());
}
)*
let name_type = (&version).try_into()?;
if let Some(class_type) = ClassType::from_name_and_type(resource.class_name, name_type) {
return match class_type {
$(
ClassType::$class => Ok(<&crate::bigfile::resource::Resource as crate::traits::TryIntoVersionPlatform<$crate::macros::classes::classes!(@class_ty $class)>>::try_into_version_platform(resource, version, platform)?.into()),
)*
};
}
Err(crate::error::UnimplementedClassError::new(resource.name, resource.class_name, version, platform).into())
}
}
@ -101,12 +157,19 @@ macro_rules! classes {
type Report = ClassTryYourBestReport;
fn update_report(resource: &crate::bigfile::resource::Resource, platform: crate::bigfile::platforms::Platform, report: &mut Self::Report) {
report.total += 1;
$(
if $crate::macros::classes::classes!(@class_name_style_type $class resource.class_name).is_some() {
<$crate::macros::classes::classes!(@class_ty $class) as crate::traits::TryYourBest<&crate::bigfile::resource::Resource>>::update_report(resource, platform, &mut report.$class);
return;
}
)*
let Some(name_type) = crate::names::active_name_type() else {
return;
};
let Some(class_type) = ClassType::from_name_and_type(resource.class_name, name_type) else {
return;
};
match class_type {
$(
ClassType::$class => {
<$crate::macros::classes::classes!(@class_ty $class) as crate::traits::TryYourBest<&crate::bigfile::resource::Resource>>::update_report(resource, platform, &mut report.$class);
}
)*
}
}
}
};
@ -127,8 +190,8 @@ macro_rules! classes {
};
(@emit_class_names_fn $($class:ident)*) => {
pub fn class_names() -> &'static[&'static str] {
&[$(<$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<&'static str>>::NAME,<$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<&'static str>>::NAME_LEGACY,)*]
pub fn class_base_names() -> &'static[&'static str] {
&[ $(stringify!($class),)* ]
}
};
@ -158,28 +221,9 @@ macro_rules! classes {
}
};
(@class_name_style_type $class:ident $name:expr) => {{
match $name {
crate::names::Name::Asobo32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsobo32>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::Asobo32)),
crate::names::Name::Asobo32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsobo32>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::Asobo32)),
crate::names::Name::AsoboAlternate32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsoboAlternate32>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::AsoboAlternate32)),
crate::names::Name::AsoboAlternate32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsoboAlternate32>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::AsoboAlternate32)),
crate::names::Name::Kalisto32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameKalisto32>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::Kalisto32)),
crate::names::Name::Kalisto32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameKalisto32>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::Kalisto32)),
crate::names::Name::BlackSheep32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameBlackSheep32>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::BlackSheep32)),
crate::names::Name::BlackSheep32(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameBlackSheep32>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::BlackSheep32)),
crate::names::Name::Asobo64(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsobo64>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::Asobo64)),
crate::names::Name::Asobo64(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameAsobo64>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::Asobo64)),
crate::names::Name::Ubisoft64(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameUbisoft64>>::NAME => Some((crate::names::NameStyle::Z, crate::names::NameType::Ubisoft64)),
crate::names::Name::Ubisoft64(n) if n == <$crate::macros::classes::classes!(@class_ty $class) as crate::traits::NamedClass<crate::names::NameUbisoft64>>::NAME_LEGACY => Some((crate::names::NameStyle::Caps, crate::names::NameType::Ubisoft64)),
_ => None,
}
}};
(@module $class:ident) => {
pastey::paste! {
pub mod [<#$class:snake>] {
$crate::macros::classes::classes!(@named_class $class);
$crate::macros::classes::classes!(@declare_class_kind_impl $class {});
}
}
@ -196,51 +240,11 @@ macro_rules! classes {
pub mod $variant_mod;
use self::$variant_mod::$variant;
)*
$crate::macros::classes::classes!(@named_class $class);
$crate::macros::classes::classes!(@declare_class_kind_impl $class { $($pattern => $variant),* });
}
}
};
(@named_class $class:ident) => {
pastey::paste! {
impl crate::traits::NamedClass<crate::names::NameAsobo32> for $class {
const NAME: crate::names::NameAsobo32 = crate::names::NameAsobo32::new(crate::crc::asobo32(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameAsobo32 = crate::names::NameAsobo32::new(crate::crc::asobo32(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<crate::names::NameAsoboAlternate32> for $class {
const NAME: crate::names::NameAsoboAlternate32 = crate::names::NameAsoboAlternate32::new(crate::crc::asobo_alternate32(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameAsoboAlternate32 = crate::names::NameAsoboAlternate32::new(crate::crc::asobo_alternate32(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<crate::names::NameKalisto32> for $class {
const NAME: crate::names::NameKalisto32 = crate::names::NameKalisto32::new(crate::crc::kalisto32(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameKalisto32 = crate::names::NameKalisto32::new(crate::crc::kalisto32(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<crate::names::NameBlackSheep32> for $class {
const NAME: crate::names::NameBlackSheep32 = crate::names::NameBlackSheep32::new(crate::crc::blacksheep32(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameBlackSheep32 = crate::names::NameBlackSheep32::new(crate::crc::blacksheep32(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<crate::names::NameAsobo64> for $class {
const NAME: crate::names::NameAsobo64 = crate::names::NameAsobo64::new(crate::crc::asobo64(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameAsobo64 = crate::names::NameAsobo64::new(crate::crc::asobo64(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<crate::names::NameUbisoft64> for $class {
const NAME: crate::names::NameUbisoft64 = crate::names::NameUbisoft64::new(crate::crc::ubisoft64(stringify!([<$class _Z>]).as_bytes()));
const NAME_LEGACY: crate::names::NameUbisoft64 = crate::names::NameUbisoft64::new(crate::crc::ubisoft64(stringify!([<$class:upper>]).as_bytes()));
}
impl crate::traits::NamedClass<&'static str> for $class {
const NAME: &'static str = stringify!([<$class _Z>]);
const NAME_LEGACY: &'static str = stringify!([<$class:upper>]);
}
}
};
(@declare_class_kind_impl $class:ident {}) => {
#[derive(serde::Serialize, serde::Deserialize, Debug, derive_more::From, derive_more::IsVariant, bff_derive::ReferencedNames)]
pub enum $class {}
@ -258,7 +262,7 @@ macro_rules! classes {
) -> crate::BffResult<$class> {
Err(
// TODO: Pick the right name based on the algorithm and suffix for the current BigFile
crate::error::UnimplementedClassError::new(resource.name, <Self as crate::traits::NamedClass<crate::names::NameAsobo32>>::NAME.into(), version, platform).into(),
crate::error::UnimplementedClassError::new(resource.name, resource.class_name, version, platform).into(),
)
}
}
@ -360,7 +364,7 @@ macro_rules! classes {
})*
_ => Err(
// TODO: Pick the right name based on the algorithm and suffix for the current BigFile
crate::error::UnimplementedClassError::new(resource.name, <Self as crate::traits::NamedClass<crate::names::NameAsobo32>>::NAME.into(), version, platform).into(),
crate::error::UnimplementedClassError::new(resource.name, resource.class_name, version, platform).into(),
),
}
}

View file

@ -21,10 +21,99 @@ macro_rules! names {
name_style_transform(style)(string.as_ref())
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, derive_more::Display, derive_more::FromStr)]
pub enum NameType {
$($name,)*
}
pub const fn name_type_style(name_type: NameType) -> NameStyle {
match name_type {
$(NameType::$name => NameStyle::$name_style,)*
}
}
impl NameType {
pub const fn target_bits(self) -> usize {
match self {
$(
NameType::$name => core::mem::size_of::<<$name_hash_function as crate::traits::NameHashFunction>::Target>() * 8,
)*
}
}
pub const fn is_32_bit(self) -> bool {
self.target_bits() == 32
}
pub fn hash_bytes(self, bytes: &[u8]) -> crate::names::Name {
match self {
$(NameType::$name => hash_bytes_for_hash::<$name_hash_function>(bytes),)*
}
}
pub fn parse_forced_hash_name<S: AsRef<str>>(self, string: S) -> Option<(crate::names::Name, String)> {
match self {
$(NameType::$name => parse_forced_hash_name_for_hash::<$name_hash_function, S>(string),)*
}
}
pub fn name_from_i32(self, value: i32) -> crate::names::Name {
match self {
$(NameType::$name => name_from_i32_for_hash::<$name_hash_function>(value),)*
}
}
pub fn value_from_name(self, name: crate::names::Name) -> i64 {
match self {
$(NameType::$name => name_value_for_hash::<$name_hash_function>(name),)*
}
}
pub fn read_name<R: std::io::Read + std::io::Seek>(
self,
reader: &mut R,
endian: binrw::Endian,
) -> binrw::BinResult<crate::names::Name> {
match self {
$(NameType::$name => read_name_for_hash::<$name_hash_function, R>(reader, endian),)*
}
}
pub fn write_name<W: std::io::Write + std::io::Seek>(
self,
writer: &mut W,
endian: binrw::Endian,
name: crate::names::Name,
) -> binrw::BinResult<()> {
match self {
$(NameType::$name => write_name_for_hash::<$name_hash_function, W>(writer, endian, name),)*
}
}
pub fn serialize_name_value<S: serde::Serializer>(
self,
name: crate::names::Name,
serializer: S,
) -> Result<S::Ok, S::Error> {
match self {
$(NameType::$name => serialize_name_value_for_hash::<$name_hash_function, S>(name, serializer),)*
}
}
pub fn deserialize_name<'de, D, F>(
self,
deserializer: D,
add_name: F,
) -> Result<crate::names::Name, D::Error>
where
D: serde::Deserializer<'de>,
F: FnMut(&str),
{
match self {
$(NameType::$name => deserialize_name_for_hash::<$name_hash_function, D, F>(deserializer, self, add_name),)*
}
}
}
};
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,6 @@
mod big_file_io;
mod export;
mod name_hash_function;
mod named_class;
mod referenced_names;
mod try_version_platform;
mod try_your_best;
@ -9,7 +8,6 @@ mod try_your_best;
pub use big_file_io::*;
pub use export::*;
pub use name_hash_function::*;
pub use named_class::*;
pub use referenced_names::*;
pub use try_version_platform::*;
pub use try_your_best::*;

View file

@ -1,4 +0,0 @@
pub trait NamedClass<N> {
const NAME: N;
const NAME_LEGACY: N;
}

View file

@ -3,6 +3,7 @@ use std::fs::{self, File};
use std::io::Cursor;
use bff::bigfile::BigFile;
use bff::bigfile::platforms::Platform;
use bff::bigfile::resource::{BffClass, BffResourceHeader, Resource};
use bff::class::Class;
use bff::names::NameContext;
@ -23,6 +24,14 @@ fn assert_no_missing_class_names(bigfile: &BigFile, name_context: &NameContext)
}
}
fn probe_name_context<R: std::io::Read + std::io::Seek>(
reader: &mut R,
platform: Platform,
) -> NameContext {
let name_type = BigFile::probe_name_type_platform(reader, platform, &None).unwrap();
NameContext::new(name_type)
}
#[datatest::data("tests/datasets/bigfile_read.yaml")]
#[test]
fn read(bigfile_path_str: String) {
@ -30,7 +39,7 @@ fn read(bigfile_path_str: String) {
let platform = bigfile_path.extension().unwrap().try_into().unwrap();
let f = File::open(bigfile_path).unwrap();
let mut reader = BufReader::new(f);
let name_context = NameContext::default();
let name_context = probe_name_context(&mut reader, platform);
let bigfile = BigFile::read_platform(&mut reader, platform, &None, &name_context).unwrap();
assert_no_missing_class_names(&bigfile, &name_context);
}
@ -42,7 +51,7 @@ fn roundtrip_resources(bigfile_path_str: String) {
let platform = bigfile_path.extension().unwrap().try_into().unwrap();
let f = File::open(bigfile_path).unwrap();
let mut reader = BufReader::new(f);
let name_context = NameContext::default();
let name_context = probe_name_context(&mut reader, platform);
let bigfile = BigFile::read_platform(&mut reader, platform, &None, &name_context).unwrap();
let version = bigfile.manifest.version.clone();
@ -84,7 +93,7 @@ fn roundtrip(bigfile_path_str: String) {
let platform = bigfile_path.extension().unwrap().try_into().unwrap();
let data = fs::read(bigfile_path).unwrap();
let mut reader = Cursor::new(&data);
let name_context = NameContext::default();
let name_context = probe_name_context(&mut reader, platform);
let bigfile = BigFile::read_platform(&mut reader, platform, &None, &name_context).unwrap();
assert_no_missing_class_names(&bigfile, &name_context);
@ -103,7 +112,7 @@ fn read_write_read(bigfile_path_str: String) {
let platform = bigfile_path.extension().unwrap().try_into().unwrap();
let f = File::open(bigfile_path).unwrap();
let mut reader = BufReader::new(f);
let name_context = NameContext::default();
let name_context = probe_name_context(&mut reader, platform);
let bigfile = BigFile::read_platform(&mut reader, platform, &None, &name_context).unwrap();
assert_no_missing_class_names(&bigfile, &name_context);
@ -112,7 +121,7 @@ fn read_write_read(bigfile_path_str: String) {
.write(&mut writer, None, &None, &None, None, &name_context)
.unwrap();
let mut reader = Cursor::new(writer.into_inner());
let name_context = NameContext::default();
let name_context = probe_name_context(&mut reader, platform);
let bigfile2 = BigFile::read_platform(&mut reader, platform, &None, &name_context).unwrap();
assert!(bigfile == bigfile2);
}

View file

@ -14,8 +14,7 @@ fn read_write_read(cps_path_str: String) {
let cps_path = resolve_repo_data_path(&cps_path_str);
let f = File::open(cps_path).unwrap();
let mut reader = BufReader::new(f);
let name_context = NameContext::default();
name_context.set_name_type(NameType::BlackSheep32);
let name_context = NameContext::new(NameType::BlackSheep32);
read_default_cps_names(&name_context).unwrap();
let cps = Cps::read(&mut reader, Endian::Little, &name_context).unwrap();
let mut writer = Cursor::new(Vec::new());
@ -23,8 +22,7 @@ fn read_write_read(cps_path_str: String) {
.unwrap();
let mut reader = Cursor::new(writer.into_inner());
let name_context = NameContext::default();
name_context.set_name_type(NameType::BlackSheep32);
let name_context = NameContext::new(NameType::BlackSheep32);
read_default_cps_names(&name_context).unwrap();
let cps2 = Cps::read(&mut reader, Endian::Little, &name_context).unwrap();