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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use super::file::*;
use super::parser;
use assembly_core::reader::FileResult;
use assembly_core::{nom::Finish, reader::ParseAt};
use byteorder::{ReadBytesExt, LE};

use std::io::prelude::*;

pub trait TerrainReader: Read {
    fn read_terrain_header(&mut self) -> FileResult<TerrainHeader> {
        let mut header_bytes = [0u8; 15];
        self.read_exact(&mut header_bytes)?;
        let (_, header) = parser::parse_terrain_header(&header_bytes)
            .finish()
            .at(0xbeef, &header_bytes)?;
        Ok(header)
    }

    fn read_terrain_chunk(&mut self) -> FileResult<TerrainChunk> {
        let index = self.read_u32::<LE>()?;
        Ok(TerrainChunk { index })
    }

    fn read_height_map_header(&mut self) -> FileResult<HeightMapHeader> {
        let mut header_bytes = [0u8; 36];
        self.read_exact(&mut header_bytes)?;
        let (_, header) = parser::parse_height_map_header(&header_bytes)
            .finish()
            .at(0xbeef, &header_bytes)?;
        Ok(header)
    }

    fn read_height_map_data(&mut self, width: u32, height: u32) -> FileResult<Vec<f32>> {
        let len = (width * height) as usize;
        let mut bytes = Vec::with_capacity(len);
        bytes.resize(len, 0.0);
        self.read_f32_into::<LE>(bytes.as_mut_slice())?;
        Ok(bytes)
    }

    fn read_color_map_data(&mut self) -> FileResult<Vec<u32>> {
        let len = self.read_u32::<LE>()? as usize;
        let len = len * len;
        let mut bytes = vec![0; len];
        self.read_u32_into::<LE>(bytes.as_mut_slice())?;
        Ok(bytes)
    }

    fn read_embedded_file(&mut self) -> FileResult<Vec<u8>> {
        let len = self.read_u32::<LE>()? as usize;
        let mut bytes = vec![0; len];
        self.read_exact(bytes.as_mut_slice())?;
        Ok(bytes)
    }
}

impl<T> TerrainReader for T where T: Read {}