All parsing is now streaming! But lots left to do.

In particular, parsing error messages are now either terrible or
non-existent.  But it compiles and works for correct inputs!
This commit is contained in:
Nathan Vegdahl 2020-01-10 22:31:39 +09:00
parent 5196e8e2c2
commit 4f564d1474
13 changed files with 677 additions and 447 deletions

View File

@ -7,18 +7,6 @@ Scene $Scene_fr1 {
SamplesPerPixel [16] SamplesPerPixel [16]
Seed [1] Seed [1]
} }
Camera {
Fov [39.449188]
FocalDistance [10.62]
ApertureRadius [0.0]
Transform [1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 -2.779998 -8.000000 2.730010 1.0]
}
World {
BackgroundShader {
Type [Color]
Color [rec709, 0.0 0.0 0.0]
}
}
Shaders { Shaders {
SurfaceShader $Green { SurfaceShader $Green {
Type [Lambert] Type [Lambert]
@ -33,6 +21,18 @@ Scene $Scene_fr1 {
Color [rec709, 0.7295 0.7355 0.729] Color [rec709, 0.7295 0.7355 0.729]
} }
} }
World {
BackgroundShader {
Type [Color]
Color [rec709, 0.0 0.0 0.0]
}
}
Camera {
Fov [39.449188]
FocalDistance [10.62]
ApertureRadius [0.0]
Transform [1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 -2.779998 -8.000000 2.730010 1.0]
}
Assembly { Assembly {
Object $__Area { Object $__Area {
Instance { Instance {

View File

@ -7,11 +7,11 @@ Scene $Scene_fr1 {
SamplesPerPixel [16] SamplesPerPixel [16]
Seed [1] Seed [1]
} }
Camera { Shaders {
Fov [49.134342] SurfaceShader $Material {
FocalDistance [9.56] Type [Lambert]
ApertureRadius [0.25] Color [rec709, 0.8 0.8 0.8]
Transform [0.685881 0.727634 -0.010817 0.0 -0.317370 0.312469 0.895343 0.0 -0.654862 0.610666 -0.445245 0.0 7.481132 -6.507640 5.343665 1.0] }
} }
World { World {
BackgroundShader { BackgroundShader {
@ -19,11 +19,11 @@ Scene $Scene_fr1 {
Color [rec709, 0.050876 0.050876 0.050876] Color [rec709, 0.050876 0.050876 0.050876]
} }
} }
Shaders { Camera {
SurfaceShader $Material { Fov [49.134342]
Type [Lambert] FocalDistance [9.56]
Color [rec709, 0.8 0.8 0.8] ApertureRadius [0.25]
} Transform [0.685881 0.727634 -0.010817 0.0 -0.317370 0.312469 0.895343 0.0 -0.654862 0.610666 -0.445245 0.0 7.481132 -6.507640 5.343665 1.0]
} }
Assembly { Assembly {
Object $__Plane_ { Object $__Plane_ {

View File

@ -44,7 +44,7 @@ fn wavelengths(hero_wavelength: f32) -> Vec4 {
//---------------------------------------------------------------- //----------------------------------------------------------------
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum Color { pub enum Color {
XYZ(f32, f32, f32), XYZ(f32, f32, f32),
Blackbody { Blackbody {

View File

@ -47,15 +47,12 @@ use nom::bytes::complete::take_until;
use kioku::Arena; use kioku::Arena;
use data_tree::{ use data_tree::{reader::DataTreeReader, Event};
reader::{DataTreeReader, ReaderError},
Event,
};
use crate::{ use crate::{
accel::BVH4Node, accel::BVH4Node,
bbox::BBox, bbox::BBox,
parse::{parse_scene, DataTree}, parse::parse_scene,
// renderer::LightPath, // renderer::LightPath,
surface::SurfaceIntersection, surface::SurfaceIntersection,
timer::Timer, timer::Timer,
@ -242,27 +239,14 @@ fn main() {
// println!("\tParsed scene file in {:.3}s", t.tick()); // println!("\tParsed scene file in {:.3}s", t.tick());
// } // }
let mut psy_file = io::BufReader::new(File::open(fp).unwrap()); let file_path = args.value_of("input").unwrap();
let mut psy_file = io::BufReader::new(File::open(file_path).unwrap());
let mut events = DataTreeReader::new(&mut psy_file); let mut events = DataTreeReader::new(&mut psy_file);
// Iterate through scenes and render them // Iterate through scenes and render them
loop { loop {
t.tick(); t.tick();
match events.next_event() { match events.next_event() {
Ok(Event::ValidEnd) => {
break;
}
Ok(_) => {
println!("Error: invalid scene in psy file.");
break;
}
Err(e) => {
println!("Error: {:?}", e);
break;
}
// Parse a scene and render it. // Parse a scene and render it.
Ok(Event::InnerOpen { Ok(Event::InnerOpen {
type_name: "Scene", type_name: "Scene",
@ -274,9 +258,11 @@ fn main() {
} }
let arena = Arena::new().with_block_size((1 << 20) * 4); let arena = Arena::new().with_block_size((1 << 20) * 4);
let ident = ident.into::<String>(); let ident = ident.map(|v| v.to_string());
let mut scene = parse_scene(&arena, &mut events, &ident).unwrap_or_else(|e| { let scene =
e.print(&psy_contents); parse_scene(&arena, &mut events, ident.as_deref()).unwrap_or_else(|e| {
println!("Parse error: {}", e);
// e.print(&psy_contents);
panic!("Parse error."); panic!("Parse error.");
}); });
@ -384,6 +370,20 @@ fn main() {
// println!("\tTotal blocks: {}", arena_stats.2); // println!("\tTotal blocks: {}", arena_stats.2);
// } // }
} }
Ok(Event::ValidEnd) => {
break;
}
Err(e) => {
println!("Error: {:?}", e);
break;
}
Ok(_) => {
println!("Error: invalid scene in psy file.");
break;
}
} }
} }

View File

@ -2,10 +2,7 @@
use std::{io::Cursor, iter::Iterator, result::Result, slice}; use std::{io::Cursor, iter::Iterator, result::Result, slice};
use data_tree::{ use data_tree::{reader::DataTreeReader, Event};
reader::{DataTreeReader, ReaderError},
Event,
};
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
pub enum DataTree { pub enum DataTree {

View File

@ -1,9 +1,9 @@
pub mod basics; pub mod basics;
mod data_tree; // mod data_tree;
mod psy; mod psy;
mod psy_assembly; mod psy_assembly;
mod psy_light; mod psy_light;
mod psy_mesh_surface; mod psy_mesh_surface;
mod psy_surface_shader; mod psy_surface_shader;
pub use self::{data_tree::DataTree, psy::parse_scene}; pub use self::psy::parse_scene;

View File

@ -26,7 +26,6 @@ use super::{
psy_assembly::parse_assembly, psy_assembly::parse_assembly,
psy_light::parse_distant_disk_light, psy_light::parse_distant_disk_light,
psy_surface_shader::parse_surface_shader, psy_surface_shader::parse_surface_shader,
DataTree,
}; };
#[derive(Debug)] #[derive(Debug)]
@ -40,7 +39,7 @@ pub enum PsyParseError {
ExpectedIdent(usize, &'static str), // Error message ExpectedIdent(usize, &'static str), // Error message
MissingNode(usize, &'static str), // Error message MissingNode(usize, &'static str), // Error message
IncorrectLeafData(usize, &'static str), // Error message IncorrectLeafData(usize, &'static str), // Error message
WrongNodeCount(usize, &'static str, usize), // Error message, sections found WrongNodeCount(usize, &'static str), // Error message
InstancedMissingData(usize, &'static str, String), // Error message, data name InstancedMissingData(usize, &'static str, String), // Error message, data name
ReaderError(ReaderError), ReaderError(ReaderError),
} }
@ -87,15 +86,17 @@ impl PsyParseError {
println!("Line {}: {}", line, error); println!("Line {}: {}", line, error);
} }
PsyParseError::WrongNodeCount(offset, error, count) => { PsyParseError::WrongNodeCount(offset, error) => {
let line = line_count_to_byte_offset(psy_content, offset); let line = line_count_to_byte_offset(psy_content, offset);
println!("Line {}: {} Found: {}", line, error, count); println!("Line {}: {}", line, error);
} }
PsyParseError::InstancedMissingData(offset, error, ref data_name) => { PsyParseError::InstancedMissingData(offset, error, ref data_name) => {
let line = line_count_to_byte_offset(psy_content, offset); let line = line_count_to_byte_offset(psy_content, offset);
println!("Line {}: {} Data name: '{}'", line, error, data_name); println!("Line {}: {} Data name: '{}'", line, error, data_name);
} }
_ => todo!(),
} }
} }
} }
@ -124,10 +125,10 @@ fn line_count_to_byte_offset(text: &str, offset: usize) -> usize {
pub fn parse_scene<'a>( pub fn parse_scene<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader<impl BufRead>, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>, _ident: Option<&str>,
) -> Result<Scene<'a>, PsyParseError> { ) -> Result<Scene<'a>, PsyParseError> {
// Get output info. // Get output info.
let output_info = if let Event::InnerOpen { let _output_info = if let Event::InnerOpen {
type_name: "Output", type_name: "Output",
.. ..
} = events.next_event()? } = events.next_event()?
@ -138,7 +139,7 @@ pub fn parse_scene<'a>(
}; };
// Get render settings. // Get render settings.
let render_settings = if let Event::InnerOpen { let _render_settings = if let Event::InnerOpen {
type_name: "RenderSettings", type_name: "RenderSettings",
.. ..
} = events.next_event()? } = events.next_event()?
@ -148,17 +149,6 @@ pub fn parse_scene<'a>(
todo!(); // Return error. todo!(); // Return error.
}; };
// Get camera.
let camera = if let Event::InnerOpen {
type_name: "Camera",
..
} = events.next_event()?
{
parse_camera(arena, events)?
} else {
todo!(); // Return error.
};
// Get shaders. // Get shaders.
let shaders = if let Event::InnerOpen { let shaders = if let Event::InnerOpen {
type_name: "Shaders", type_name: "Shaders",
@ -180,14 +170,24 @@ pub fn parse_scene<'a>(
todo!(); // Return error. todo!(); // Return error.
}; };
// Get the root assembly. // Get camera.
let root_assembly = if let Event::InnerOpen { let camera = if let Event::InnerOpen {
type_name: "Assembly", type_name: "Camera",
ident,
.. ..
} = events.next_event()? } = events.next_event()?
{ {
parse_assembly(arena, events, &(ident.into::<String>()))? parse_camera(arena, events)?
} else {
todo!(); // Return error.
};
// Get the root assembly.
let root_assembly = if let Event::InnerOpen {
type_name: "Assembly",
..
} = events.next_event()?
{
parse_assembly(arena, events)?
} else { } else {
todo!(); // Return error. todo!(); // Return error.
}; };
@ -199,12 +199,11 @@ pub fn parse_scene<'a>(
} }
// Put scene together // Put scene together
let scene_name = if let Some(name) = ident { // let scene_name = if let Some(name) = ident {
Some(name.into()) // Some(name.into())
} else { // } else {
None // None
}; // };
let scene = Scene { let scene = Scene {
camera: camera, camera: camera,
world: world, world: world,
@ -241,13 +240,13 @@ fn parse_output_info(events: &mut DataTreeReader<impl BufRead>) -> Result<String
let tc = contents.trim(); let tc = contents.trim();
if tc.chars().count() < 2 { if tc.chars().count() < 2 {
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"File path format is incorrect.", "File path format is incorrect.",
)); ));
} }
if tc.chars().nth(0).unwrap() != '"' || !tc.ends_with('"') { if tc.chars().nth(0).unwrap() != '"' || !tc.ends_with('"') {
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"File paths must be surrounded by quotes.", "File paths must be surrounded by quotes.",
)); ));
} }
@ -304,7 +303,7 @@ fn parse_render_settings(
} else { } else {
// Found Resolution, but its contents is not in the right format // Found Resolution, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"Resolution should be specified with two \ "Resolution should be specified with two \
integers in the form '[width height]'.", integers in the form '[width height]'.",
)); ));
@ -312,7 +311,7 @@ fn parse_render_settings(
} }
// SamplesPerPixel // SamplesPerPixel
DataTree::Leaf { Event::Leaf {
type_name: "SamplesPerPixel", type_name: "SamplesPerPixel",
contents, contents,
byte_offset, byte_offset,
@ -323,7 +322,7 @@ fn parse_render_settings(
} else { } else {
// Found SamplesPerPixel, but its contents is not in the right format // Found SamplesPerPixel, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"SamplesPerPixel should be \ "SamplesPerPixel should be \
an integer specified in \ an integer specified in \
the form '[samples]'.", the form '[samples]'.",
@ -332,7 +331,7 @@ fn parse_render_settings(
} }
// Seed // Seed
DataTree::Leaf { Event::Leaf {
type_name: "Seed", type_name: "Seed",
contents, contents,
byte_offset, byte_offset,
@ -342,7 +341,7 @@ fn parse_render_settings(
} else { } else {
// Found Seed, but its contents is not in the right format // Found Seed, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"Seed should be an integer \ "Seed should be an integer \
specified in the form \ specified in the form \
'[samples]'.", '[samples]'.",
@ -395,7 +394,7 @@ fn parse_camera<'a>(
} else { } else {
// Found Fov, but its contents is not in the right format // Found Fov, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"Fov should be a decimal \ "Fov should be a decimal \
number specified in the \ number specified in the \
form '[fov]'.", form '[fov]'.",
@ -414,7 +413,7 @@ fn parse_camera<'a>(
} else { } else {
// Found FocalDistance, but its contents is not in the right format // Found FocalDistance, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"FocalDistance should be a \ "FocalDistance should be a \
decimal number specified \ decimal number specified \
in the form '[fov]'.", in the form '[fov]'.",
@ -433,7 +432,7 @@ fn parse_camera<'a>(
} else { } else {
// Found ApertureRadius, but its contents is not in the right format // Found ApertureRadius, but its contents is not in the right format
return Err(PsyParseError::IncorrectLeafData( return Err(PsyParseError::IncorrectLeafData(
*byte_offset, byte_offset,
"ApertureRadius should be a \ "ApertureRadius should be a \
decimal number specified \ decimal number specified \
in the form '[fov]'.", in the form '[fov]'.",
@ -451,7 +450,7 @@ fn parse_camera<'a>(
mats.push(mat); mats.push(mat);
} else { } else {
// Found Transform, but its contents is not in the right format // Found Transform, but its contents is not in the right format
return Err(make_transform_format_error(*byte_offset)); return Err(make_transform_format_error(byte_offset));
} }
} }
@ -478,7 +477,7 @@ fn parse_world<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader<impl BufRead>, events: &mut DataTreeReader<impl BufRead>,
) -> Result<World<'a>, PsyParseError> { ) -> Result<World<'a>, PsyParseError> {
let background_color = None; let mut background_color = None;
let mut lights: Vec<&dyn WorldLightSource> = Vec::new(); let mut lights: Vec<&dyn WorldLightSource> = Vec::new();
loop { loop {
@ -486,25 +485,26 @@ fn parse_world<'a>(
// Parse background shader // Parse background shader
Event::InnerOpen { Event::InnerOpen {
type_name: "BackgroundShader", type_name: "BackgroundShader",
..
} => { } => {
let bgs_type = if let Event::Leaf { let bgs_type = if let Event::Leaf {
type_name: "Type", type_name: "Type",
contents, contents,
.. ..
} = events.next_event() } = events.next_event()?
{ {
contents.into::<String>() contents.to_string()
} else { } else {
todo!(); // Return error. todo!(); // Return error.
}; };
match bgs_type { match bgs_type.as_ref() {
"Color" => { "Color" => {
if let Event::Leaf { if let Event::Leaf {
type_name: "Color", type_name: "Color",
contents, contents,
.. ..
} = events.next_event() } = events.next_event()?
{ {
background_color = Some(parse_color(contents)?); background_color = Some(parse_color(contents)?);
} else { } else {
@ -524,7 +524,7 @@ fn parse_world<'a>(
} }
// Close it out. // Close it out.
if let Event::InnerClose { .. } = events.next_event() { if let Event::InnerClose { .. } = events.next_event()? {
} else { } else {
todo!(); // Return error. todo!(); // Return error.
} }
@ -533,9 +533,23 @@ fn parse_world<'a>(
// Parse light sources // Parse light sources
Event::InnerOpen { Event::InnerOpen {
type_name: "DistantDiskLight", type_name: "DistantDiskLight",
ident,
.. ..
} => { } => {
lights.push(arena.alloc(parse_distant_disk_light(arena, events)?)); let ident = ident.map(|v| v.to_string());
lights.push(arena.alloc(parse_distant_disk_light(
arena,
events,
ident.as_deref(),
)?));
}
Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return error.
} }
} }
} }
@ -552,24 +566,32 @@ fn parse_world<'a>(
} }
fn parse_shaders<'a>( fn parse_shaders<'a>(
arena: &'a Arena,
events: &mut DataTreeReader<impl BufRead>, events: &mut DataTreeReader<impl BufRead>,
) -> Result<HashMap<String, Box<dyn SurfaceShader>>, PsyParseError> { ) -> Result<HashMap<String, Box<dyn SurfaceShader>>, PsyParseError> {
let mut shaders = HashMap::new(); let mut shaders = HashMap::new();
loop { loop {
match events.next_event() { match events.next_event()? {
DataTree::Internal { Event::InnerOpen {
type_name: "SurfaceShader", type_name: "SurfaceShader",
ident, ident,
byte_offset, ..
} => { } => {
if let Some(name) = ident { if let Some(name) = ident {
let name = name.to_string(); let name = name.to_string();
shaders.insert(name, parse_surface_shader(events)?); shaders.insert(
name.clone(),
parse_surface_shader(arena, events, Some(&name))?,
);
} else { } else {
todo!("Shader has no name."); // Return error. todo!("Shader has no name."); // Return error.
} }
} }
Event::InnerClose { .. } => {
break;
}
_ => { _ => {
todo!(); // Return error. todo!(); // Return error.
} }

View File

@ -1,13 +1,10 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::result::Result; use std::{io::BufRead, result::Result};
use kioku::Arena; use kioku::Arena;
use data_tree::{ use data_tree::{reader::DataTreeReader, Event};
reader::{DataTreeReader, ReaderError},
Event,
};
use crate::scene::{Assembly, Object, ObjectData}; use crate::scene::{Assembly, Object, ObjectData};
@ -15,101 +12,137 @@ use super::{
psy::{parse_matrix, PsyParseError}, psy::{parse_matrix, PsyParseError},
psy_light::{parse_rectangle_light, parse_sphere_light}, psy_light::{parse_rectangle_light, parse_sphere_light},
psy_mesh_surface::parse_mesh_surface, psy_mesh_surface::parse_mesh_surface,
DataTree,
}; };
pub fn parse_assembly<'a>( pub fn parse_assembly<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>,
) -> Result<Assembly<'a>, PsyParseError> { ) -> Result<Assembly<'a>, PsyParseError> {
if !tree.is_internal() {
return Err(PsyParseError::UnknownError(tree.byte_offset()));
}
let mut assembly = Assembly::new(); let mut assembly = Assembly::new();
for object in tree.iter_children() { loop {
if object.type_name() == "Object" { match events.next_event()? {
Event::InnerOpen {
type_name: "Object",
ident,
byte_offset,
} => {
// Get object identifier. // Get object identifier.
let object_ident = if let Some(ident) = object.ident() { let object_ident = if let Some(id) = ident {
ident id.to_string()
} else { } else {
return Err(PsyParseError::ExpectedIdent( return Err(PsyParseError::ExpectedIdent(
object.byte_offset(), byte_offset,
"\'Object\' types must have an identifier, but the identifier is missing.", "\'Object\' types must have an identifier, but the identifier is missing.",
)); ));
}; };
// Collect instances. // Collect instances.
let mut instance_xform_idxs = Vec::new(); let mut instance_xform_idxs = Vec::new();
for instance in object.iter_children_with_type("Instance") { while let Event::InnerOpen {
if !instance.is_internal() { type_name: "Instance",
// TODO: error. ..
} } = events.peek_event()?
{
events.next_event();
let xforms_start_idx = assembly.xforms.len(); let xforms_start_idx = assembly.xforms.len();
for (_, contents, _) in instance.iter_leaf_children_with_type("Transform") { loop {
match events.next_event()? {
Event::Leaf {
type_name: "Transform",
contents,
..
} => {
assembly.xforms.push(parse_matrix(contents)?); assembly.xforms.push(parse_matrix(contents)?);
} }
Event::InnerClose { .. } => {
break;
}
_ => {
todo!("Instances can only contain Transforms.");
// Return an error.
}
}
}
instance_xform_idxs.push(xforms_start_idx..assembly.xforms.len()); instance_xform_idxs.push(xforms_start_idx..assembly.xforms.len());
} }
// Get object data. // Get object data.
let object_data = { let object_data = match events.next_event()? {
let obj_data_tree = { Event::InnerOpen {
if object type_name: "Assembly",
.iter_children() ..
.filter(|d| d.type_name() != "Instance") } => ObjectData::Assembly(Box::new(parse_assembly(arena, events)?)),
.count()
!= 1
{
// TODO: error.
}
object
.iter_children()
.filter(|d| d.type_name() != "Instance")
.nth(0)
.unwrap()
};
match obj_data_tree.type_name() { Event::InnerOpen {
// Sub-Assembly type_name: "MeshSurface",
"Assembly" => { ..
ObjectData::Assembly(Box::new(parse_assembly(arena, obj_data_tree)?)) } => ObjectData::Surface(Box::new(parse_mesh_surface(arena, events)?)),
}
"MeshSurface" => { Event::InnerOpen {
ObjectData::Surface(Box::new(parse_mesh_surface(arena, obj_data_tree)?)) type_name: "SphereLight",
} ..
} => ObjectData::Light(Box::new(parse_sphere_light(arena, events)?)),
"SphereLight" => { Event::InnerOpen {
ObjectData::Light(Box::new(parse_sphere_light(arena, obj_data_tree)?)) type_name: "RectangleLight",
} ..
} => ObjectData::Light(Box::new(parse_rectangle_light(arena, events)?)),
"RectangleLight" => { Event::InnerClose { byte_offset } => {
ObjectData::Light(Box::new(parse_rectangle_light(arena, obj_data_tree)?)) return Err(PsyParseError::MissingNode(
byte_offset,
"Object contains no object data.",
));
} }
_ => { _ => {
return Err(PsyParseError::UnknownVariant( return Err(PsyParseError::UnknownVariant(
tree.byte_offset(), byte_offset,
"Unknown data type for Object.", "Unknown data type for Object.",
)); ));
} }
}
}; };
// Close object node.
if let Event::InnerClose { .. } = events.next_event()? {
// Success, do nothing.
} else {
todo!(); // Return error.
}
assembly.objects.insert( assembly.objects.insert(
object_ident.to_string(), object_ident,
Object { Object {
data: object_data, data: object_data,
instance_xform_idxs: instance_xform_idxs, instance_xform_idxs: instance_xform_idxs,
}, },
); );
} else { }
// TODO: error.
Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return an error.
}
} }
} }
// if !tree.is_internal() {
// return Err(PsyParseError::UnknownError(tree.byte_offset()));
// }
// for object in tree.iter_children() {
// if object.type_name() == "Object" {
// } else {
// // TODO: error.
// }
// }
return Ok(assembly); return Ok(assembly);
} }

View File

@ -1,15 +1,12 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::result::Result; use std::{io::BufRead, result::Result};
use nom::{combinator::all_consuming, sequence::tuple, IResult}; use nom::{combinator::all_consuming, sequence::tuple, IResult};
use kioku::Arena; use kioku::Arena;
use data_tree::{ use data_tree::{reader::DataTreeReader, Event};
reader::{DataTreeReader, ReaderError},
Event,
};
use crate::{ use crate::{
light::{DistantDiskLight, RectangleLight, SphereLight}, light::{DistantDiskLight, RectangleLight, SphereLight},
@ -19,174 +16,175 @@ use crate::{
use super::{ use super::{
basics::ws_f32, basics::ws_f32,
psy::{parse_color, PsyParseError}, psy::{parse_color, PsyParseError},
DataTree,
}; };
pub fn parse_distant_disk_light<'a>( pub fn parse_distant_disk_light<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>, _ident: Option<&str>,
) -> Result<DistantDiskLight<'a>, PsyParseError> { ) -> Result<DistantDiskLight<'a>, PsyParseError> {
if let DataTree::Internal { ref children, .. } = *tree {
let mut radii = Vec::new(); let mut radii = Vec::new();
let mut directions = Vec::new(); let mut directions = Vec::new();
let mut colors = Vec::new(); let mut colors = Vec::new();
// Parse // Parse
for child in children.iter() { loop {
match child { match events.next_event()? {
// Radius Event::Leaf {
DataTree::Leaf { type_name: "Radius",
type_name,
contents, contents,
byte_offset, byte_offset,
} if type_name == "Radius" => { } => {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) { if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) {
radii.push(radius); radii.push(radius);
} else { } else {
// Found radius, but its contents is not in the right format // Found radius, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
// Direction // Direction
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Direction",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Direction" => { } => {
if let IResult::Ok((_, direction)) = if let IResult::Ok((_, direction)) =
all_consuming(tuple((ws_f32, ws_f32, ws_f32)))(&contents) all_consuming(tuple((ws_f32, ws_f32, ws_f32)))(&contents)
{ {
directions.push(Vector::new(direction.0, direction.1, direction.2)); directions.push(Vector::new(direction.0, direction.1, direction.2));
} else { } else {
// Found direction, but its contents is not in the right format // Found direction, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
// Color // Color
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Color",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Color" => { } => {
if let Ok(color) = parse_color(&contents) { if let Ok(color) = parse_color(&contents) {
colors.push(color); colors.push(color);
} else { } else {
// Found color, but its contents is not in the right format // Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
_ => {} Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return error.
}
} }
} }
return Ok(DistantDiskLight::new(arena, &radii, &directions, &colors)); return Ok(DistantDiskLight::new(arena, &radii, &directions, &colors));
} else {
return Err(PsyParseError::UnknownError(tree.byte_offset()));
}
} }
pub fn parse_sphere_light<'a>( pub fn parse_sphere_light<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>,
) -> Result<SphereLight<'a>, PsyParseError> { ) -> Result<SphereLight<'a>, PsyParseError> {
if let DataTree::Internal { ref children, .. } = *tree {
let mut radii = Vec::new(); let mut radii = Vec::new();
let mut colors = Vec::new(); let mut colors = Vec::new();
// Parse // Parse
for child in children.iter() { loop {
match child { match events.next_event()? {
// Radius // Radius
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Radius",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Radius" => { } => {
if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) { if let IResult::Ok((_, radius)) = all_consuming(ws_f32)(&contents) {
radii.push(radius); radii.push(radius);
} else { } else {
// Found radius, but its contents is not in the right format // Found radius, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
// Color // Color
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Color",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Color" => { } => {
if let Ok(color) = parse_color(&contents) { if let Ok(color) = parse_color(&contents) {
colors.push(color); colors.push(color);
} else { } else {
// Found color, but its contents is not in the right format // Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
_ => {} Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return error.
}
} }
} }
return Ok(SphereLight::new(arena, &radii, &colors)); return Ok(SphereLight::new(arena, &radii, &colors));
} else {
return Err(PsyParseError::UnknownError(tree.byte_offset()));
}
} }
pub fn parse_rectangle_light<'a>( pub fn parse_rectangle_light<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>,
) -> Result<RectangleLight<'a>, PsyParseError> { ) -> Result<RectangleLight<'a>, PsyParseError> {
if let DataTree::Internal { ref children, .. } = *tree {
let mut dimensions = Vec::new(); let mut dimensions = Vec::new();
let mut colors = Vec::new(); let mut colors = Vec::new();
// Parse // Parse
for child in children.iter() { loop {
match child { match events.next_event()? {
// Dimensions // Dimensions
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Dimensions",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Dimensions" => { } => {
if let IResult::Ok((_, radius)) = if let IResult::Ok((_, radius)) = all_consuming(tuple((ws_f32, ws_f32)))(&contents)
all_consuming(tuple((ws_f32, ws_f32)))(&contents)
{ {
dimensions.push(radius); dimensions.push(radius);
} else { } else {
// Found dimensions, but its contents is not in the right format // Found dimensions, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
// Color // Color
DataTree::Leaf { Event::Leaf {
type_name, type_name: "Color",
contents, contents,
byte_offset, byte_offset,
} if type_name == "Color" => { } => {
if let Ok(color) = parse_color(&contents) { if let Ok(color) = parse_color(&contents) {
colors.push(color); colors.push(color);
} else { } else {
// Found color, but its contents is not in the right format // Found color, but its contents is not in the right format
return Err(PsyParseError::UnknownError(*byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} }
_ => {} Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return error.
}
} }
} }
return Ok(RectangleLight::new(arena, &dimensions, &colors)); return Ok(RectangleLight::new(arena, &dimensions, &colors));
} else {
return Err(PsyParseError::UnknownError(tree.byte_offset()));
}
} }

View File

@ -1,15 +1,12 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::result::Result; use std::{io::BufRead, result::Result};
use nom::{sequence::tuple, IResult}; use nom::{sequence::tuple, IResult};
use kioku::Arena; use kioku::Arena;
use data_tree::{ use data_tree::{reader::DataTreeReader, Event};
reader::{DataTreeReader, ReaderError},
Event,
};
use crate::{ use crate::{
math::{Normal, Point}, math::{Normal, Point},
@ -19,7 +16,6 @@ use crate::{
use super::{ use super::{
basics::{ws_f32, ws_usize}, basics::{ws_f32, ws_usize},
psy::PsyParseError, psy::PsyParseError,
DataTree,
}; };
// pub struct TriangleMesh { // pub struct TriangleMesh {
@ -31,20 +27,29 @@ use super::{
pub fn parse_mesh_surface<'a>( pub fn parse_mesh_surface<'a>(
arena: &'a Arena, arena: &'a Arena,
events: &mut DataTreeReader, events: &mut DataTreeReader<impl BufRead>,
ident: Option<&str>,
) -> Result<TriangleMesh<'a>, PsyParseError> { ) -> Result<TriangleMesh<'a>, PsyParseError> {
let mut verts = Vec::new(); // Vec of vecs, one for each time sample let mut verts = Vec::new(); // Vec of vecs, one for each time sample
let mut normals = Vec::new(); // Vec of vecs, on for each time sample let mut normals = Vec::new(); // Vec of vecs, on for each time sample
let mut face_vert_counts = Vec::new(); let mut face_vert_counts = Vec::new();
let mut face_vert_indices = Vec::new(); let mut face_vert_indices = Vec::new();
// TODO: make sure there are the right number of various children, loop {
// and other validation. match events.next_event()? {
Event::Leaf {
type_name: "SurfaceShaderBind",
..
} => {
// TODO
}
// Get verts Event::Leaf {
for (_, mut text, _) in tree.iter_leaf_children_with_type("Vertices") { type_name: "Vertices",
contents,
..
} => {
// Collect verts for this time sample // Collect verts for this time sample
let mut text = contents;
let mut tverts = Vec::new(); let mut tverts = Vec::new();
while let IResult::Ok((remaining, vert)) = tuple((ws_f32, ws_f32, ws_f32))(text) { while let IResult::Ok((remaining, vert)) = tuple((ws_f32, ws_f32, ws_f32))(text) {
text = remaining; text = remaining;
@ -54,15 +59,13 @@ pub fn parse_mesh_surface<'a>(
verts.push(tverts); verts.push(tverts);
} }
// Make sure all time samples have same vert count Event::Leaf {
let vert_count = verts[0].len(); type_name: "Normals",
for vs in &verts { contents,
assert_eq!(vert_count, vs.len()); ..
} } => {
// Get normals, if they exist
for (_, mut text, _) in tree.iter_leaf_children_with_type("Normals") {
// Collect normals for this time sample // Collect normals for this time sample
let mut text = contents;
let mut tnormals = Vec::new(); let mut tnormals = Vec::new();
while let IResult::Ok((remaining, nor)) = tuple((ws_f32, ws_f32, ws_f32))(text) { while let IResult::Ok((remaining, nor)) = tuple((ws_f32, ws_f32, ws_f32))(text) {
text = remaining; text = remaining;
@ -72,7 +75,60 @@ pub fn parse_mesh_surface<'a>(
normals.push(tnormals); normals.push(tnormals);
} }
// Make sure normal's time samples and vert count match the vertices Event::Leaf {
type_name: "FaceVertCounts",
contents,
byte_offset,
} => {
if !face_vert_counts.is_empty() {
return Err(PsyParseError::WrongNodeCount(
byte_offset,
"Meshes can only have one FaceVertCounts section.",
));
}
let mut text = contents;
while let IResult::Ok((remaining, count)) = ws_usize(text) {
text = remaining;
face_vert_counts.push(count);
}
}
Event::Leaf {
type_name: "FaceVertIndices",
contents,
byte_offset,
} => {
if !face_vert_indices.is_empty() {
return Err(PsyParseError::WrongNodeCount(
byte_offset,
"Meshes can only have one FaceVertIndices section.",
));
}
let mut text = contents;
while let IResult::Ok((remaining, index)) = ws_usize(text) {
text = remaining;
face_vert_indices.push(index);
}
}
Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return error.
}
}
}
// Validation: make sure all time samples have same vert count.
let vert_count = verts[0].len();
for vs in &verts {
assert_eq!(vert_count, vs.len());
}
// Validation: make sure normal's time samples and vert count match
// the vertices.
if !normals.is_empty() { if !normals.is_empty() {
assert_eq!(normals.len(), verts.len()); assert_eq!(normals.len(), verts.len());
for ns in &normals { for ns in &normals {
@ -80,22 +136,10 @@ pub fn parse_mesh_surface<'a>(
} }
} }
// Get face vert counts // Validation: make sure we have any mesh data.
if let Some((_, mut text, _)) = tree.iter_leaf_children_with_type("FaceVertCounts").nth(0) { if verts.is_empty() || face_vert_counts.is_empty() || face_vert_indices.is_empty() {
while let IResult::Ok((remaining, count)) = ws_usize(text) { todo!("Meshes must have at least one non-empty of each of the following sections: Vertices, FaceVertCounts, FaceVertIndices.");
text = remaining; // Return an error.
face_vert_counts.push(count);
}
}
// Get face vert indices
if let Some((_, mut text, _)) = tree.iter_leaf_children_with_type("FaceVertIndices").nth(0) {
while let IResult::Ok((remaining, index)) = ws_usize(text) {
text = remaining;
face_vert_indices.push(index);
}
} }
// Build triangle mesh // Build triangle mesh

View File

@ -1,20 +1,18 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::result::Result; use std::{io::BufRead, result::Result};
use nom::{combinator::all_consuming, IResult}; use nom::{combinator::all_consuming, IResult};
use data_tree::{ use kioku::Arena;
reader::{DataTreeReader, ReaderError},
Event, use data_tree::{reader::DataTreeReader, Event};
};
use crate::shading::{SimpleSurfaceShader, SurfaceShader}; use crate::shading::{SimpleSurfaceShader, SurfaceShader};
use super::{ use super::{
basics::ws_f32, basics::ws_f32,
psy::{parse_color, PsyParseError}, psy::{parse_color, PsyParseError},
DataTree,
}; };
// pub struct TriangleMesh { // pub struct TriangleMesh {
@ -25,22 +23,22 @@ use super::{
// } // }
pub fn parse_surface_shader( pub fn parse_surface_shader(
events: &mut DataTreeReader, _arena: &Arena,
ident: Option<&str>, events: &mut DataTreeReader<impl BufRead>,
_ident: Option<&str>,
) -> Result<Box<dyn SurfaceShader>, PsyParseError> { ) -> Result<Box<dyn SurfaceShader>, PsyParseError> {
let type_name = if let Some((_, text, _)) = tree.iter_leaf_children_with_type("Type").nth(0) { // Get shader type.
text.trim() let shader = match events.next_event()? {
} else { Event::Leaf {
return Err(PsyParseError::MissingNode( type_name: "Type",
tree.byte_offset(), contents: "Lambert",
"Expected a Type field in SurfaceShader.", ..
)); } => {
}; let color = if let Event::Leaf {
type_name: "Color",
let shader = match type_name { contents,
"Lambert" => { byte_offset,
let color = if let Some((_, contents, byte_offset)) = } = events.next_event()?
tree.iter_leaf_children_with_type("Color").nth(0)
{ {
if let Ok(color) = parse_color(contents) { if let Ok(color) = parse_color(contents) {
color color
@ -50,74 +48,108 @@ pub fn parse_surface_shader(
} }
} else { } else {
return Err(PsyParseError::MissingNode( return Err(PsyParseError::MissingNode(
tree.byte_offset(), events.byte_offset(),
"Expected a Color field in Lambert SurfaceShader.", "Expected a Color field in Lambert SurfaceShader.",
)); ));
}; };
// Close shader node.
if let Event::InnerClose { .. } = events.next_event()? {
// Success, do nothing.
} else {
todo!(); // Return error.
}
Box::new(SimpleSurfaceShader::Lambert { color: color }) Box::new(SimpleSurfaceShader::Lambert { color: color })
} }
"GGX" => { Event::Leaf {
type_name: "Type",
contents: "GGX",
..
} => {
let mut color = None;
let mut roughness = None;
let mut fresnel = None;
loop {
match events.next_event()? {
// Color // Color
let color = if let Some((_, contents, byte_offset)) = Event::Leaf {
tree.iter_leaf_children_with_type("Color").nth(0) type_name: "Color",
{ contents,
if let Ok(color) = parse_color(contents) { byte_offset,
color } => {
if let Ok(col) = parse_color(contents) {
color = Some(col);
} else { } else {
// Found color, but its contents is not in the right format // Found color, but its contents is not in the right
// format.
return Err(PsyParseError::UnknownError(byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} else { }
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Color field in GTR SurfaceShader.",
));
};
// Roughness // Roughness
let roughness = if let Some((_, contents, byte_offset)) = Event::Leaf {
tree.iter_leaf_children_with_type("Roughness").nth(0) type_name: "Roughness",
{ contents,
if let IResult::Ok((_, roughness)) = all_consuming(ws_f32)(contents) { byte_offset,
roughness } => {
if let IResult::Ok((_, rgh)) = all_consuming(ws_f32)(contents) {
roughness = Some(rgh);
} else { } else {
return Err(PsyParseError::UnknownError(byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} else { }
return Err(PsyParseError::MissingNode(
tree.byte_offset(),
"Expected a Roughness field in GTR SurfaceShader.",
));
};
// Fresnel // Fresnel
let fresnel = if let Some((_, contents, byte_offset)) = Event::Leaf {
tree.iter_leaf_children_with_type("Fresnel").nth(0) type_name: "Fresnel",
{ contents,
if let IResult::Ok((_, fresnel)) = all_consuming(ws_f32)(contents) { byte_offset,
fresnel } => {
if let IResult::Ok((_, frs)) = all_consuming(ws_f32)(contents) {
fresnel = Some(frs);
} else { } else {
return Err(PsyParseError::UnknownError(byte_offset)); return Err(PsyParseError::UnknownError(byte_offset));
} }
} else { }
Event::InnerClose { .. } => {
break;
}
_ => {
todo!(); // Return an error.
}
}
}
// Validation: make sure all fields are present.
if color == None || roughness == None || fresnel == None {
return Err(PsyParseError::MissingNode( return Err(PsyParseError::MissingNode(
tree.byte_offset(), events.byte_offset(),
"Expected a Fresnel field in GTR SurfaceShader.", "GGX shader requires one of each field: Color, Roughness, Fresnel.",
)); ));
}; }
Box::new(SimpleSurfaceShader::GGX { Box::new(SimpleSurfaceShader::GGX {
color: color, color: color.unwrap(),
roughness: roughness, roughness: roughness.unwrap(),
fresnel: fresnel, fresnel: fresnel.unwrap(),
}) })
} }
"Emit" => { Event::Leaf {
let color = if let Some((_, contents, byte_offset)) = type_name: "Type",
tree.iter_leaf_children_with_type("Color").nth(0) contents: "Emit",
..
} => {
let color = if let Event::Leaf {
type_name: "Color",
contents,
byte_offset,
} = events.next_event()?
{ {
if let Ok(color) = parse_color(contents) { if let Ok(color) = parse_color(contents) {
color color
@ -127,15 +159,34 @@ pub fn parse_surface_shader(
} }
} else { } else {
return Err(PsyParseError::MissingNode( return Err(PsyParseError::MissingNode(
tree.byte_offset(), events.byte_offset(),
"Expected a Color field in Emit SurfaceShader.", "Expected a Color field in Emit SurfaceShader.",
)); ));
}; };
// Close shader node.
if let Event::InnerClose { .. } = events.next_event()? {
// Success, do nothing.
} else {
todo!(); // Return error.
}
Box::new(SimpleSurfaceShader::Emit { color: color }) Box::new(SimpleSurfaceShader::Emit { color: color })
} }
_ => unimplemented!(), Event::Leaf {
type_name: "Type",
byte_offset,
..
} => {
return Err(PsyParseError::MissingNode(
byte_offset,
"Unknown SurfaceShader type.",
));
}
_ => {
todo!(); // Return error.
}
}; };
Ok(shader) Ok(shader)

View File

@ -127,8 +127,6 @@ impl Parser {
self.buf_consumed_idx += bytes_consumed; self.buf_consumed_idx += bytes_consumed;
self.total_bytes_processed += bytes_consumed; self.total_bytes_processed += bytes_consumed;
// Hack the borrow checker, which doesn't understand
// loops apparently, and return.
Ok(event.add_to_byte_offset(self.total_bytes_processed - self.buf_consumed_idx)) Ok(event.add_to_byte_offset(self.total_bytes_processed - self.buf_consumed_idx))
} }
EventParse::ReachedEnd => { EventParse::ReachedEnd => {
@ -157,6 +155,56 @@ impl Parser {
)), )),
} }
} }
pub fn peek_event<'a>(&'a mut self) -> Result<Event<'a>, Error> {
// Remove any consumed data.
if self.buf_consumed_idx > 0 {
self.buffer.replace_range(..self.buf_consumed_idx, "");
self.buf_consumed_idx = 0;
}
// Try to parse an event from the valid prefix.
match try_parse_event(&self.buffer) {
EventParse::Ok(event, _bytes_consumed) => {
if let Event::InnerClose { byte_offset, .. } = event {
if self.inner_opens == 0 {
return Err(Error::UnexpectedClose(
byte_offset + self.total_bytes_processed,
));
}
}
Ok(event.add_to_byte_offset(self.total_bytes_processed))
}
EventParse::ReachedEnd => {
// If we consumed all data, then if all nodes are properly
// closed we're done. Otherwise we need more input.
if self.inner_opens == 0 {
Ok(Event::ValidEnd)
} else {
Ok(Event::NeedMoreInput)
}
}
EventParse::IncompleteData => Ok(Event::NeedMoreInput),
// Hard errors.
EventParse::ExpectedTypeNameOrInnerClose(byte_offset) => Err(
Error::ExpectedTypeNameOrClose(byte_offset + self.total_bytes_processed),
),
EventParse::ExpectedOpenOrIdent(byte_offset) => Err(Error::ExpectedOpenOrIdent(
byte_offset + self.total_bytes_processed,
)),
EventParse::ExpectedInnerOpen(byte_offset) => Err(Error::ExpectedOpen(
byte_offset + self.total_bytes_processed,
)),
EventParse::UnexpectedIdent(byte_offset) => Err(Error::UnexpectedIdent(
byte_offset + self.total_bytes_processed,
)),
}
}
pub fn byte_offset(&self) -> usize {
self.total_bytes_processed + self.buf_consumed_idx
}
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View File

@ -81,4 +81,41 @@ impl<R: std::io::BufRead> DataTreeReader<R> {
} }
} }
} }
pub fn peek_event<'a>(&'a mut self) -> Result<Event<'a>, ReaderError> {
loop {
let valid_end = match self.parser.peek_event()? {
Event::ValidEnd => true,
Event::NeedMoreInput => false,
e => {
return Ok(unsafe {
// Transmute because the borrow checker is
// over-conservative about this. It thinks
// the liftime isn't valid, but since we aren't
// mutating self after returning (and in fact
// can't because of the borrow) there's no way for
// the references in this to become invalid.
std::mem::transmute::<Event, Event>(e)
});
}
};
if !self.eof {
self.buf.clear();
let read = self.reader.read_line(&mut self.buf)?;
self.parser.push_data(&self.buf);
if read == 0 {
self.eof = true;
}
} else if !valid_end {
return Err(ReaderError::UnexpectedEOF);
} else {
return Ok(Event::ValidEnd);
}
}
}
pub fn byte_offset(&self) -> usize {
self.parser.byte_offset()
}
} }