///|
/// A seekable cursor over a bounded, complete Bytes buffer; not OS/file streaming.
/// Records are decoded on demand and a failed next() leaves the position unchanged.
pub struct PointCursor {
data : Bytes
header : Header
mut index : Int32
}
///|
pub fn open_records(
data : Bytes,
limits~ : Limits = Limits::default(),
) -> PointCursor raise LasError {
let header = read_header(data, limits~)
ignore(read_vlrs(data, header, limits~))
require(
data.length() - header.point_offset ==
header.point_count * header.record_length,
"trailing bytes after point records",
)
{ data, header, index: 0, }
}
///|
pub fn PointCursor::header(self : PointCursor) -> Header {
self.header
}
///|
pub fn PointCursor::remaining(self : PointCursor) -> Int32 {
self.header.point_count - self.index
}
///|
pub fn PointCursor::position(self : PointCursor) -> Int32 {
self.index
}
///|
pub fn PointCursor::seek(
self : PointCursor,
index : Int32,
) -> Unit raise LasError {
require(
index >= 0 && index <= self.header.point_count,
"cursor index outside records",
)
self.index = index
}
///|
pub fn PointCursor::next(self : PointCursor) -> Point? raise LasError {
if self.remaining() == 0 {
return None
}
let start = self.header.point_offset + self.index * self.header.record_length
let r = Reader::new(self.data, start, start + self.header.record_length)
let p = read_point(r.take(self.header.record_length), self.header.format)
self.index += 1
Some(p)
}
///|
/// At most n records, bounded by remaining input. Negative n is rejected.
pub fn PointCursor::batch(
self : PointCursor,
n : Int32,
) -> Array[Point] raise LasError {
require(n >= 0, "negative batch size")
let size = if n < self.remaining() { n } else { self.remaining() }
let points : Array[Point] = []
for _ in 0.. points.push(p)
None => ()
}
}
points
}