use crate::{PointRecord, Result};
pub trait PointReader {
fn read_point(&mut self, out: &mut PointRecord) -> Result<bool>;
fn point_count(&self) -> Option<u64>;
fn read_all(&mut self) -> Result<Vec<PointRecord>> {
let mut points = Vec::new();
if let Some(total) = self.point_count() {
if let Ok(hint) = usize::try_from(total) {
let _ = points.try_reserve(hint);
}
}
let mut p = PointRecord::default();
while self.read_point(&mut p)? {
points.push(p);
}
Ok(points)
}
}
pub trait SeekableReader: PointReader {
fn seek_to_point(&mut self, index: u64) -> Result<()>;
}
pub trait PointWriter {
fn write_point(&mut self, point: &PointRecord) -> Result<()>;
fn finish(&mut self) -> Result<()>;
fn write_all_points(&mut self, points: &[PointRecord]) -> Result<()> {
for p in points {
self.write_point(p)?;
}
Ok(())
}
}
#[allow(dead_code)]
pub(crate) mod le {
use std::io::{self, Read, Write};
#[inline]
pub fn read_u8<R: Read>(r: &mut R) -> io::Result<u8> {
let mut b = [0u8; 1];
r.read_exact(&mut b)?;
Ok(b[0])
}
#[inline]
pub fn read_u16<R: Read>(r: &mut R) -> io::Result<u16> {
let mut b = [0u8; 2];
r.read_exact(&mut b)?;
Ok(u16::from_le_bytes(b))
}
#[inline]
pub fn read_u32<R: Read>(r: &mut R) -> io::Result<u32> {
let mut b = [0u8; 4];
r.read_exact(&mut b)?;
Ok(u32::from_le_bytes(b))
}
#[inline]
pub fn read_u64<R: Read>(r: &mut R) -> io::Result<u64> {
let mut b = [0u8; 8];
r.read_exact(&mut b)?;
Ok(u64::from_le_bytes(b))
}
#[inline]
pub fn read_i8<R: Read>(r: &mut R) -> io::Result<i8> {
read_u8(r).map(|v| v as i8)
}
#[inline]
pub fn read_i16<R: Read>(r: &mut R) -> io::Result<i16> {
let mut b = [0u8; 2];
r.read_exact(&mut b)?;
Ok(i16::from_le_bytes(b))
}
#[inline]
pub fn read_i32<R: Read>(r: &mut R) -> io::Result<i32> {
let mut b = [0u8; 4];
r.read_exact(&mut b)?;
Ok(i32::from_le_bytes(b))
}
#[inline]
pub fn read_f32<R: Read>(r: &mut R) -> io::Result<f32> {
let mut b = [0u8; 4];
r.read_exact(&mut b)?;
Ok(f32::from_le_bytes(b))
}
#[inline]
pub fn read_f64<R: Read>(r: &mut R) -> io::Result<f64> {
let mut b = [0u8; 8];
r.read_exact(&mut b)?;
Ok(f64::from_le_bytes(b))
}
#[inline]
pub fn write_u8<W: Write>(w: &mut W, v: u8) -> io::Result<()> { w.write_all(&[v]) }
#[inline]
pub fn write_u16<W: Write>(w: &mut W, v: u16) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_u32<W: Write>(w: &mut W, v: u32) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_u64<W: Write>(w: &mut W, v: u64) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_i8<W: Write>(w: &mut W, v: i8) -> io::Result<()> {
w.write_all(&[v as u8])
}
#[inline]
pub fn write_i16<W: Write>(w: &mut W, v: i16) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_i32<W: Write>(w: &mut W, v: i32) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_f32<W: Write>(w: &mut W, v: f32) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
#[inline]
pub fn write_f64<W: Write>(w: &mut W, v: f64) -> io::Result<()> {
w.write_all(&v.to_le_bytes())
}
}
#[cfg(test)]
mod tests {
use super::PointReader;
use crate::{PointRecord, Result};
struct HugeCountEmptyReader;
impl PointReader for HugeCountEmptyReader {
fn read_point(&mut self, _out: &mut PointRecord) -> Result<bool> {
Ok(false)
}
fn point_count(&self) -> Option<u64> {
Some(u64::MAX)
}
}
#[test]
fn read_all_does_not_abort_on_huge_header_hint() {
let mut r = HugeCountEmptyReader;
let pts = r.read_all().expect("read_all should handle oversized hint safely");
assert!(pts.is_empty());
}
}
#[allow(dead_code)]
pub(crate) mod be {
use std::io::{self, Read, Write};
#[inline]
pub fn read_u16<R: Read>(r: &mut R) -> io::Result<u16> {
let mut b = [0u8; 2]; r.read_exact(&mut b)?; Ok(u16::from_be_bytes(b))
}
#[inline]
pub fn read_u32<R: Read>(r: &mut R) -> io::Result<u32> {
let mut b = [0u8; 4]; r.read_exact(&mut b)?; Ok(u32::from_be_bytes(b))
}
#[inline]
pub fn read_f32<R: Read>(r: &mut R) -> io::Result<f32> {
let mut b = [0u8; 4]; r.read_exact(&mut b)?; Ok(f32::from_be_bytes(b))
}
#[inline]
pub fn read_f64<R: Read>(r: &mut R) -> io::Result<f64> {
let mut b = [0u8; 8]; r.read_exact(&mut b)?; Ok(f64::from_be_bytes(b))
}
#[inline]
pub fn write_u32<W: Write>(w: &mut W, v: u32) -> io::Result<()> {
w.write_all(&v.to_be_bytes())
}
#[inline]
pub fn write_f32<W: Write>(w: &mut W, v: f32) -> io::Result<()> {
w.write_all(&v.to_be_bytes())
}
#[inline]
pub fn write_f64<W: Write>(w: &mut W, v: f64) -> io::Result<()> {
w.write_all(&v.to_be_bytes())
}
}
#[allow(dead_code)]
pub(crate) fn buffered_file_reader(path: &std::path::Path)
-> std::io::Result<std::io::BufReader<std::fs::File>>
{
let f = std::fs::File::open(path)?;
Ok(std::io::BufReader::with_capacity(256 * 1024, f))
}
#[allow(dead_code)]
pub(crate) fn buffered_file_writer(path: &std::path::Path)
-> std::io::Result<std::io::BufWriter<std::fs::File>>
{
let f = std::fs::File::create(path)?;
Ok(std::io::BufWriter::with_capacity(256 * 1024, f))
}