more parsing progress
This commit is contained in:
parent
83f26f90b0
commit
0a38732db3
1 changed files with 125 additions and 3 deletions
128
src/lib.rs
128
src/lib.rs
|
@ -1,7 +1,10 @@
|
|||
#![feature(array_chunks)]
|
||||
#![feature(iter_collect_into)]
|
||||
|
||||
use std::{collections::HashMap, io::Read};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::{self, Read},
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
|
||||
|
@ -20,7 +23,126 @@ impl PropertyTree {
|
|||
where
|
||||
R: Read,
|
||||
{
|
||||
Ok(PropertyTree::None)
|
||||
let first_byte = reader
|
||||
.by_ref()
|
||||
.bytes()
|
||||
.next()
|
||||
.ok_or(anyhow!("Unexpected EOF"))
|
||||
.context("Failed trying to get PropertyTreeType")??;
|
||||
|
||||
match first_byte {
|
||||
0 => Ok(PropertyTree::None),
|
||||
1 => Self::parse_bool(reader),
|
||||
2 => Self::parse_number(reader),
|
||||
3 => Ok(PropertyTree::String(Self::parse_string(reader)?)),
|
||||
4 => Self::parse_list(reader),
|
||||
5 => Self::parse_dictionary(reader),
|
||||
b => Err(anyhow!("Invalid PropertyTreeType {b} expected <6")),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_dictionary<R>(reader: &mut R) -> anyhow::Result<PropertyTree>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
// Skip the byte between the PropertyTreeType and the first byte of the length
|
||||
io::copy(&mut reader.by_ref().take(1), &mut io::sink())
|
||||
.context("Failed to skip any-type flag: Likely early EoF")?;
|
||||
|
||||
let elements = Self::parse_unsigned_int(reader)?;
|
||||
let out = HashMap::with_capacity(elements as usize);
|
||||
|
||||
Ok(PropertyTree::Dictionary(out))
|
||||
}
|
||||
|
||||
fn parse_list<R>(_reader: &mut R) -> anyhow::Result<PropertyTree>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
Ok(PropertyTree::List(Vec::new()))
|
||||
}
|
||||
|
||||
fn parse_string<R>(reader: &mut R) -> anyhow::Result<String>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
// TODO: Investigate this
|
||||
let _string_exists = reader
|
||||
.by_ref()
|
||||
.bytes()
|
||||
.next()
|
||||
.ok_or(anyhow!("Unexpected EoF"))
|
||||
.context("Failed trying to get bool for string")??;
|
||||
|
||||
let length = Self::parse_space_optimized_unsigned_int(reader)
|
||||
.context("Failed to get length of string")?;
|
||||
|
||||
let mut string = String::new();
|
||||
reader
|
||||
.by_ref()
|
||||
.take(length as u64)
|
||||
.read_to_string(&mut string)
|
||||
.context("Failed reading string bytes")?;
|
||||
|
||||
// TODO: Handle not enough bytes here
|
||||
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
/// parses a u32_le
|
||||
fn parse_unsigned_int<R>(reader: &mut R) -> anyhow::Result<u32>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let mut buf = [0u8; 4];
|
||||
reader
|
||||
.read_exact(&mut buf)
|
||||
.context("Failed trying to get bytes for an unsigned int")?;
|
||||
|
||||
println!("{buf:?}");
|
||||
|
||||
Ok(u32::from_le_bytes(buf))
|
||||
}
|
||||
|
||||
/// parses a u32_le
|
||||
fn parse_space_optimized_unsigned_int<R>(reader: &mut R) -> anyhow::Result<u32>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let first_byte = reader
|
||||
.by_ref()
|
||||
.bytes()
|
||||
.next()
|
||||
.ok_or(anyhow!("Unexpected EoF"))
|
||||
.context("Failed trying to get bytes for space optimized unsigned int")??;
|
||||
|
||||
Ok(match first_byte {
|
||||
255 => Self::parse_unsigned_int(reader).context(
|
||||
"Failed trying to get full length int from space optimized unsigned int",
|
||||
)?,
|
||||
value => value as u32,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_number<R>(_reader: &mut R) -> anyhow::Result<PropertyTree>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
Ok(PropertyTree::Number(0.0))
|
||||
}
|
||||
|
||||
fn parse_bool<R>(reader: &mut R) -> anyhow::Result<PropertyTree>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let first_byte = reader
|
||||
.by_ref()
|
||||
.bytes()
|
||||
.next()
|
||||
.ok_or(anyhow!("Unexpected EoF"))
|
||||
.context("Failed trying to get boolean value")??;
|
||||
|
||||
Ok(PropertyTree::Bool(first_byte.to_le() == 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +171,7 @@ impl ModSettings {
|
|||
.by_ref()
|
||||
.bytes()
|
||||
.next()
|
||||
.ok_or(anyhow!("Unexpected EOF"))
|
||||
.ok_or(anyhow!("Unexpected EoF"))
|
||||
.context("Failed trying to grab null byte that follows version number");
|
||||
|
||||
// Mapping pairs of 2 u8s into single le u16s
|
||||
|
|
Loading…
Reference in a new issue