diff --git a/Cargo.lock b/Cargo.lock index 88dc59b..5ab0091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,296 +1,297 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080" dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] name = "ansi_term" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5", ] [[package]] name = "atty" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "termion", + "winapi 0.3.5", ] [[package]] name = "bitflags" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" [[package]] name = "byteorder" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" [[package]] name = "clap" version = "2.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", ] [[package]] name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags", + "fuchsia-zircon-sys", ] [[package]] name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "gcmod" version = "0.1.0" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "clap", + "regex", + "tempfile", ] [[package]] name = "kernel32-sys" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8", + "winapi-build", ] [[package]] name = "lazy_static" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" [[package]] name = "libc" version = "0.2.42" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" [[package]] name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] name = "rand" version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon", + "libc", + "rand 0.4.2", ] [[package]] name = "rand" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon", + "libc", + "winapi 0.3.5", ] [[package]] name = "redox_syscall" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" [[package]] name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" dependencies = [ - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall", ] [[package]] name = "regex" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e" dependencies = [ - "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", + "utf8-ranges", ] [[package]] name = "regex-syntax" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54" dependencies = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util", ] [[package]] name = "strsim" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" [[package]] name = "tempfile" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys", + "libc", + "rand 0.3.22", + "redox_syscall", + "winapi 0.2.8", ] [[package]] name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_syscall", + "redox_termios", ] [[package]] name = "textwrap" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width", ] [[package]] name = "thread_local" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" dependencies = [ - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "unreachable", ] [[package]] name = "ucd-util" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" [[package]] name = "unicode-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" [[package]] name = "unreachable" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "void", ] [[package]] name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" [[package]] name = "vec_map" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" [[package]] name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" [[package]] name = "winapi" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1" -"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" -"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" -"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e" -"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum tempfile 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "11ce2fe9db64b842314052e2421ac61a73ce41b898dc8e3750398b219c5fc1e0" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 4d9bcf1..d35745a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "gcmod" version = "0.1.0" +edition = "2021" authors = ["Addison Bean "] [dependencies] byteorder = "1" clap = "2" tempfile = "2.2.0" -lazy_static = "1.0" regex = "1" diff --git a/src/game.rs b/src/game.rs index ebb326e..6f6aa1d 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,23 +1,26 @@ -use std::collections::BTreeMap; -use std::fs::{create_dir, File}; -use std::io::{self, BufRead, Seek}; -use std::path::Path; - -use sections::apploader::{Apploader, APPLOADER_OFFSET}; -use sections::dol::DOLHeader; -use sections::dol::segment::Segment; -use sections::fst::{ - entry::DirectoryEntry, - FST, +use std::{ + collections::BTreeMap, + fs::{create_dir, File}, + io::{self, BufRead, Seek}, + path::Path }; -use sections::header::{GAME_HEADER_SIZE, Header}; -use ::{ + +use crate::{ format_u64, - NumberStyle, paths::*, + sections::{ + apploader::{Apploader, APPLOADER_OFFSET}, + dol::{segment::Segment, DOLHeader}, + fst::{ + entry::DirectoryEntry, + FST, + }, + header::{Header, GAME_HEADER_SIZE}, + Section, + }, + NumberStyle, }; -use sections::Section; pub const ROM_SIZE: usize = 0x57058000; diff --git a/src/lib.rs b/src/lib.rs index 69fc668..383af21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,35 +1,30 @@ -extern crate byteorder; -#[macro_use] -extern crate lazy_static; -extern crate regex; - -use std::borrow::Cow; -use std::cmp::min; -use std::fmt; -use std::io::{self, Read, Write}; -use std::num::ParseIntError; +use std::{ + borrow::Cow, + cmp::min, + fmt, + io::{self, Read, Write}, + num::ParseIntError, +}; mod game; -pub use game::Game; -pub use game::ROM_SIZE; - +mod rom_rebuilder; pub mod sections; -mod rom_rebuilder; +pub use game::{Game, ROM_SIZE}; pub use rom_rebuilder::ROMRebuilder; // 1048576 = 2^20 = 1MiB, there's no real good reason behind this choice -pub const WRITE_CHUNK_SIZE: usize = 1048576; +pub const WRITE_CHUNK_SIZE: usize = 1048576; // 32KiB -pub const DEFAULT_ALIGNMENT: u64 = 32 * 1024; +pub const DEFAULT_ALIGNMENT: u64 = 32 * 1024; pub const MIN_ALIGNMENT: u64 = 4; pub mod paths { - pub const APPLOADER_PATH: &'static str = "&&systemdata/Apploader.ldr"; - pub const DOL_PATH: &'static str = "&&systemdata/Start.dol"; - pub const FST_PATH: &'static str = "&&systemdata/Game.toc"; - pub const HEADER_PATH: &'static str = "&&systemdata/ISO.hdr"; + pub const APPLOADER_PATH: &str = "&&systemdata/Apploader.ldr"; + pub const DOL_PATH: &str = "&&systemdata/Start.dol"; + pub const FST_PATH: &str = "&&systemdata/Game.toc"; + pub const HEADER_PATH: &str = "&&systemdata/ISO.hdr"; } pub fn extract_section( diff --git a/src/main.rs b/src/main.rs index 75c258a..9c84fc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,10 @@ -#[macro_use] -extern crate clap; -extern crate gcmod; -extern crate tempfile; - -use std::fs::{remove_file, File}; -use std::io::BufReader; -use std::path::Path; +use std::{ + fs::{remove_file, File}, + io::BufReader, + path::Path, +}; -use clap::AppSettings; +use clap::{clap_app, AppSettings}; use gcmod::{ AppError, @@ -20,6 +17,7 @@ use gcmod::{ NumberStyle, parse_as_u64, ROM_SIZE, + ROMRebuilder, sections::{ apploader::Apploader, dol::DOLHeader, @@ -28,7 +26,6 @@ use gcmod::{ Section, }, }; -use gcmod::ROMRebuilder; fn main() -> AppResult { let app = clap_app!(app => @@ -72,13 +69,13 @@ fn main() -> AppResult { ).setting(AppSettings::SubcommandRequired); match app.get_matches().subcommand() { - ("extract", Some(cmd)) => + ("extract", Some(cmd)) => extract_iso( cmd.value_of("rom_path").unwrap(), cmd.value_of("output").unwrap(), cmd.value_of("rom_section"), ), - ("info", Some(cmd)) => + ("info", Some(cmd)) => get_info( cmd.value_of("rom_path").unwrap(), cmd.value_of("type"), diff --git a/src/rom_rebuilder.rs b/src/rom_rebuilder.rs index 22a494c..fe2901d 100644 --- a/src/rom_rebuilder.rs +++ b/src/rom_rebuilder.rs @@ -1,20 +1,25 @@ -use std::cmp; -use std::fs::{File, read_dir}; -use std::io::{self, BufReader, Write}; -use std::path::{self, Path, PathBuf}; -use std::sync::Mutex; - -use sections::apploader::APPLOADER_OFFSET; -use sections::fst::{ - FST, - entry::{DirectoryEntry, Entry, EntryInfo, FileEntry}, +use std::{ + cmp, + fs::{read_dir, File}, + io::{self, BufReader, Write}, + iter, + path::{self, Path, PathBuf}, + sync::OnceLock, }; -use sections::header::Header; -use ::{ + +use crate::{ align, - DEFAULT_ALIGNMENT, extract_section, paths::*, + sections::{ + apploader::APPLOADER_OFFSET, + fst::{ + entry::{DirectoryEntry, Entry, EntryInfo, FileEntry}, + FST + }, + header::Header, + }, + DEFAULT_ALIGNMENT, WRITE_CHUNK_SIZE, }; @@ -129,7 +134,7 @@ impl<'a> FSTRebuilder<'a> { size, }; let fst_path = self.config.root_path.join(FST_PATH); - fst.write(File::create(&fst_path)?)?; + fst.write(File::create(fst_path)?)?; self.config.space_used = Some(max_eof); @@ -178,11 +183,11 @@ impl<'a> FSTRebuilder<'a> { let filename = e.file_name(); let filename = filename.to_string_lossy(); - if FSTRebuilder::is_file_ignored(&*filename) { + if FSTRebuilder::is_file_ignored(&filename) { continue } - let index = rb_info.entries.len() as usize; + let index = rb_info.entries.len(); let info = EntryInfo { index, name: filename.clone().into_owned(), @@ -234,8 +239,8 @@ impl<'a> HeaderRebuilder<'a> { let header_buf = BufReader::new(File::open(&header_path)?); let mut header = Header::new(header_buf, 0)?; - header.dol_offset = self.dol_offset as u64; - header.fst_offset = self.fst.offset as u64; + header.dol_offset = self.dol_offset; + header.fst_offset = self.fst.offset; header.fst_size = self.fst.size; // TODO: Is this okay to assume? @@ -351,7 +356,7 @@ impl ROMRebuilder { let total_files = self.files.len(); for (i, &(offset, ref filename)) in self.files.iter().enumerate() { - let mut file = File::open(filename)?; + let file = File::open(filename)?; let size = file.metadata()?.len(); if size == 0 { continue } @@ -359,7 +364,7 @@ impl ROMRebuilder { write_zeros((offset - bytes_written) as usize, &mut output)?; bytes_written = offset; - extract_section(&mut file, size as usize, &mut output)?; + extract_section(&file, size as usize, &mut output)?; bytes_written += size; if bytes_written as usize > ROM_SIZE { @@ -386,17 +391,17 @@ impl ROMRebuilder { } } -fn write_zeros(count: usize, mut output: impl Write) -> io::Result<()> { - lazy_static! { - static ref ZEROS: Mutex> = Mutex::new(vec![]); - } - let mut zeros = ZEROS.lock().unwrap(); - let block_size = cmp::min(count, WRITE_CHUNK_SIZE); - zeros.resize(block_size, 0); - for i in 0..(count / WRITE_CHUNK_SIZE + 1) { - (&mut output).write_all( - &zeros[..cmp::min(WRITE_CHUNK_SIZE, count - WRITE_CHUNK_SIZE * i)] - )?; +fn write_zeros(mut remaining: usize, mut output: impl Write) -> io::Result<()> { + static ZEROS: OnceLock> = OnceLock::new(); + let zeros = ZEROS.get_or_init(|| + iter::repeat(0).take(WRITE_CHUNK_SIZE).collect() + ); + + while remaining > 0 { + let count = cmp::min(WRITE_CHUNK_SIZE, remaining); + output.write_all(&zeros[..count])?; + remaining -= count; } + Ok(()) } diff --git a/src/sections/apploader.rs b/src/sections/apploader.rs index 3381427..225c04b 100644 --- a/src/sections/apploader.rs +++ b/src/sections/apploader.rs @@ -2,16 +2,15 @@ use std::io::{self, Read, Seek, SeekFrom, Write}; use byteorder::{BigEndian, ReadBytesExt}; -use ::{ +use crate::{ align, extract_section, format_u64, format_usize, NumberStyle, + sections::Section, }; -use sections::Section; - pub const APPLOADER_OFFSET: u64 = 0x2440; const APPLOADER_DATE_SIZE: usize = 0x0A; const APPLOADER_ENTRY_POINT_ADDR: u64 = 0x2450; @@ -35,7 +34,7 @@ impl Apploader { reader.seek(SeekFrom::Start(offset))?; let mut date = String::new(); reader.take(APPLOADER_DATE_SIZE as u64).read_to_string(&mut date)?; - + reader.seek(SeekFrom::Current(6))?; // it's just fluff let entry_point = reader.read_u32::()? as u64; diff --git a/src/sections/dol/mod.rs b/src/sections/dol/mod.rs index 15f45eb..690d546 100644 --- a/src/sections/dol/mod.rs +++ b/src/sections/dol/mod.rs @@ -1,21 +1,20 @@ -pub mod segment; - -use std::cmp::max; -use std::io::{self, Read, Seek, SeekFrom, Write}; -use std::iter::Iterator; +use std::{ + cmp::max, + io::{self, Read, Seek, SeekFrom, Write}, +}; use byteorder::{BigEndian, ReadBytesExt}; -use ::{ +use crate::{ extract_section, format_u64, format_usize, + sections::Section, NumberStyle, }; -use self::segment::{Segment, SegmentType}; - -use sections::Section; +pub mod segment; +use segment::{Segment, SegmentType}; const TEXT_SEG_COUNT: usize = 7; const DATA_SEG_COUNT: usize = 11; diff --git a/src/sections/dol/segment.rs b/src/sections/dol/segment.rs index 30f8d02..87621e8 100644 --- a/src/sections/dol/segment.rs +++ b/src/sections/dol/segment.rs @@ -1,9 +1,13 @@ use std::io::{Write, Seek, SeekFrom, Read, self}; -use regex::Regex; - -use ::{format_u64, format_usize, NumberStyle, parse_as_u64, extract_section}; -use sections::Section; +use crate::{ + extract_section, + format_u64, + format_usize, + parse_as_u64, + sections::Section, + NumberStyle, +}; #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] pub enum SegmentType { @@ -60,21 +64,13 @@ impl Segment { } pub fn parse_segment_name(name: &str) -> Option<(SegmentType, u64)> { - use self::SegmentType::*; - lazy_static! { - static ref SEG_NAME_REGEX: Regex = - Regex::new(r"^\.?(text|data)(\d+)$").unwrap(); - } - SEG_NAME_REGEX.captures(name).and_then(|c| { - parse_as_u64(c.get(2).unwrap().as_str()).map(|n| { - let t = match c.get(1).unwrap().as_str() { - "text" => Text, - "data" => Data, - _ => unreachable!(), - }; - (t, n) - }).ok() - }) + let (kind, suffix) = + if let Some(suffix) = name.strip_prefix(".text") { (SegmentType::Text, suffix) } + else if let Some(suffix) = name.strip_prefix(".data") { (SegmentType::Data, suffix) } + else { return None; }; + + let n = parse_as_u64(suffix).ok()?; + Some((kind, n)) } // TODO: put in a trait diff --git a/src/sections/fst/entry.rs b/src/sections/fst/entry.rs index a5fdbfc..f9cc96e 100644 --- a/src/sections/fst/entry.rs +++ b/src/sections/fst/entry.rs @@ -1,19 +1,24 @@ -use std::fs::{create_dir_all, File}; -use std::io::{self, BufRead, Seek, SeekFrom, Write}; -use std::path::{self, Path, PathBuf}; +use std::{ + fs::{create_dir_all, File}, + io::{self, BufRead, Seek, SeekFrom, Write}, + path::{self, Path, PathBuf}, +}; use byteorder::{BigEndian, ReadBytesExt}; -use ::{extract_section, format_u64, format_usize, NumberStyle}; -use sections::Section; +use crate::{ + extract_section, + format_u64, + format_usize, + sections::Section, + NumberStyle, +}; pub const ENTRY_SIZE: usize = 12; // writes in big endian fn write_int_to_buffer(num: u64, buf: &mut [u8]) { - for i in 0..buf.len() { - buf[i] = ((num >> 8 * (buf.len() - i - 1)) & 0xff) as u8; - } + buf.copy_from_slice(&num.to_be_bytes()) } #[derive(Debug)] @@ -315,4 +320,3 @@ impl Section for FileEntry { self.size } } - diff --git a/src/sections/fst/mod.rs b/src/sections/fst/mod.rs index e774e00..6f91f7a 100644 --- a/src/sections/fst/mod.rs +++ b/src/sections/fst/mod.rs @@ -1,24 +1,24 @@ -pub mod entry; - -use std::cmp::max; -use std::collections::BTreeMap; -use std::io::{self, BufRead, Read, Seek, SeekFrom, Write}; -use std::path::{Path, PathBuf}; +use std::{ + cmp::max, + collections::BTreeMap, + io::{self, BufRead, Read, Seek, SeekFrom, Write}, + path::{Path, PathBuf}, +}; use byteorder::{BigEndian, ReadBytesExt}; -use sections::Section; -use ::{ +use crate::{ extract_section, format_u64, format_usize, NumberStyle, + sections::Section, }; -use self::entry::{DirectoryEntry, Entry, EntryInfo, ENTRY_SIZE}; - +pub mod entry; +use entry::{DirectoryEntry, Entry, EntryInfo, ENTRY_SIZE}; -pub const FST_OFFSET_OFFSET: u64 = 0x0424; +pub const FST_OFFSET_OFFSET: u64 = 0x0424; pub const FST_SIZE_OFFSET: u64 = 0x0428; #[derive(Debug)] @@ -83,13 +83,13 @@ impl FST { entries.push(e); } - let str_tbl_addr = iso.seek(SeekFrom::Current(0))?; + let str_tbl_addr = iso.stream_position()?; let mut end = 0; for e in entries.iter_mut() { e.read_filename(&mut iso, str_tbl_addr)?; - let curr_end = iso.seek(SeekFrom::Current(0))?; + let curr_end = iso.stream_position()?; end = max(curr_end, end); } @@ -118,7 +118,7 @@ impl FST { } pub fn extract_file_system( - &mut self, + &mut self, path: impl AsRef, iso: impl BufRead + Seek, callback: impl FnMut(usize), @@ -145,9 +145,9 @@ impl FST { sorted_names.insert(e.info().filename_offset, &e.info().name); } let null_byte = [0]; - for (_, name) in &sorted_names { - (&mut writer).write(name.as_bytes())?; - (&mut writer).write(&null_byte[..])?; + for name in sorted_names.values() { + writer.write_all(name.as_bytes())?; + writer.write_all(&null_byte[..])?; } Ok(()) } diff --git a/src/sections/header.rs b/src/sections/header.rs index 9ea1f88..c2eb417 100644 --- a/src/sections/header.rs +++ b/src/sections/header.rs @@ -5,15 +5,14 @@ use std::io::{self, BufRead, Read, Seek, SeekFrom, Write}; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use ::{ +use crate::{ extract_section, format_u64, format_usize, NumberStyle, + sections::Section, }; -use sections::Section; - pub const GAME_HEADER_SIZE: usize = 0x2440; pub const GAMEID_SIZE: usize = 6; @@ -96,7 +95,7 @@ impl HeaderInformation { where R: Read + Seek, { - file.seek(SeekFrom::Start(offset as u64))?; + file.seek(SeekFrom::Start(offset))?; Ok(HeaderInformation { debug_monitor_size: file.read_u32::()?, simulated_memory_size: file.read_u32::()?, @@ -127,7 +126,7 @@ impl Header { where R: BufRead + Seek, { - file.seek(SeekFrom::Start(offset as u64))?; + file.seek(SeekFrom::Start(offset))?; let mut game_code = String::with_capacity(GAME_CODE_SIZE); file.by_ref().take(GAME_CODE_SIZE as u64) .read_to_string(&mut game_code)?; @@ -182,7 +181,7 @@ impl Header { let user_length = file.read_u32::()?; let unknown = file.read_u32::()?; - let pos = file.seek(SeekFrom::Current(0))?; + let pos = file.stream_position()?; let information = HeaderInformation::new(file, pos)?; diff --git a/src/sections/mod.rs b/src/sections/mod.rs index 8c970ff..ef60139 100644 --- a/src/sections/mod.rs +++ b/src/sections/mod.rs @@ -4,4 +4,4 @@ pub mod fst; pub mod header; mod section; -pub use self::section::Section; +pub use section::Section; diff --git a/src/sections/section.rs b/src/sections/section.rs index a4f5be1..a64e4a6 100644 --- a/src/sections/section.rs +++ b/src/sections/section.rs @@ -1,6 +1,5 @@ -use crate::NumberStyle; -use std::cmp::Ordering::*; use std::cmp::Ordering; +use crate::NumberStyle; pub trait Section { fn print_info(&self, style: NumberStyle); @@ -15,11 +14,11 @@ pub trait Section { fn compare_offset(&self, offset: u64) -> Ordering { if self.end() < offset { - Less + Ordering::Less } else if self.start() > offset { - Greater + Ordering::Greater } else { - Equal + Ordering::Equal } } }