io/region: use ChunkArray to parse region header

A layout of a ChunkArray::<u32> matches the binary format of the region
header.
This commit is contained in:
Matthias Schiffer 2023-01-27 22:12:02 +01:00
parent 28b22ce423
commit daa188eb1d
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 15 additions and 9 deletions

7
Cargo.lock generated
View file

@ -20,6 +20,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytemuck"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -202,6 +208,7 @@ name = "minedmap"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytemuck",
"clap", "clap",
"fastnbt", "fastnbt",
"flate2", "flate2",

View file

@ -9,6 +9,7 @@ default-run = "minedmap"
[dependencies] [dependencies]
anyhow = "1.0.68" anyhow = "1.0.68"
bytemuck = "1.13.0"
clap = { version = "4.1.4", features = ["derive"] } clap = { version = "4.1.4", features = ["derive"] }
fastnbt = "2.3.2" fastnbt = "2.3.2"
flate2 = "1.0.25" flate2 = "1.0.25"

View file

@ -19,20 +19,18 @@ struct ChunkDesc {
len: u8, len: u8,
} }
fn parse_header(header: &[u8; BLOCKSIZE]) -> HashMap<u32, ChunkDesc> { fn parse_header(header: &ChunkArray<u32>) -> HashMap<u32, ChunkDesc> {
let mut map = HashMap::new(); let mut map = HashMap::new();
for coords in ChunkArray::<()>::keys() { for (coords, &chunk) in header.iter() {
let chunk = &header[(4 let offset_len = u32::from_be(chunk);
* (usize::from(CHUNKS_PER_REGION) * usize::from(coords.z.0)
+ usize::from(coords.x.0)))..];
let offset = u32::from(chunk[0]) << 16 | u32::from(chunk[1]) << 8 | u32::from(chunk[2]); let offset = offset_len >> 8;
if offset == 0 { if offset == 0 {
continue; continue;
} }
let len = chunk[3]; let len = offset_len as u8;
map.insert(offset, ChunkDesc { coords, len }); map.insert(offset, ChunkDesc { coords, len });
} }
@ -81,9 +79,9 @@ impl<R: Read + Seek> Region<R> {
let Region { mut reader } = self; let Region { mut reader } = self;
let mut chunk_map = { let mut chunk_map = {
let mut header = [0u8; BLOCKSIZE]; let mut header = ChunkArray::<u32>::default();
reader reader
.read_exact(&mut header) .read_exact(bytemuck::cast_mut::<_, [u8; BLOCKSIZE]>(&mut header.0))
.context("Failed to read region header")?; .context("Failed to read region header")?;
parse_header(&header) parse_header(&header)