more parsing progress

This commit is contained in:
Zynh0722 2023-11-23 22:10:20 -08:00
parent 83f26f90b0
commit 0a38732db3

View file

@ -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