use crate::{Blob, ByteRange};
use anyhow::{Context, Result, bail};
use byteorder::{ByteOrder, ReadBytesExt};
use std::io::{Read, Seek};
pub trait SeekRead: Seek + Read {}
#[allow(dead_code)]
pub trait ValueReader<'a, E: ByteOrder + 'a> {
fn get_reader(&mut self) -> &mut dyn SeekRead;
fn len(&self) -> u64;
fn position(&mut self) -> u64;
fn set_position(&mut self, position: u64) -> Result<()>;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn remaining(&mut self) -> u64 {
self.len() - self.position()
}
fn has_remaining(&mut self) -> bool {
self.remaining() > 0
}
fn read_varint(&mut self) -> Result<u64> {
let mut value = 0;
let mut shift = 0;
loop {
let byte = self.get_reader().read_u8()?;
value |= (u64::from(byte) & 0x7F) << shift;
if byte & 0x80 == 0 {
break;
}
shift += 7;
if shift >= 70 {
bail!("Varint too long");
}
}
Ok(value)
}
fn read_svarint(&mut self) -> Result<i64> {
let sint_value = i64::try_from(self.read_varint()?)?;
Ok((sint_value >> 1) ^ -(sint_value & 1))
}
fn read_f32(&mut self) -> Result<f32> {
Ok(self.get_reader().read_f32::<E>()?)
}
fn read_f64(&mut self) -> Result<f64> {
Ok(self.get_reader().read_f64::<E>()?)
}
fn read_u8(&mut self) -> Result<u8> {
Ok(self.get_reader().read_u8()?)
}
fn read_i16(&mut self) -> Result<i16> {
Ok(self.get_reader().read_i16::<E>()?)
}
fn read_i32(&mut self) -> Result<i32> {
Ok(self.get_reader().read_i32::<E>()?)
}
fn read_i64(&mut self) -> Result<i64> {
Ok(self.get_reader().read_i64::<E>()?)
}
fn read_u16(&mut self) -> Result<u16> {
Ok(self.get_reader().read_u16::<E>()?)
}
fn read_u32(&mut self) -> Result<u32> {
Ok(self.get_reader().read_u32::<E>()?)
}
fn read_u64(&mut self) -> Result<u64> {
Ok(self.get_reader().read_u64::<E>()?)
}
fn read_blob(&mut self, length: u64) -> Result<Blob> {
let mut blob = Blob::new_sized(usize::try_from(length).context("Blob length too large for this platform")?);
self.get_reader().read_exact(blob.as_mut_slice())?;
Ok(blob)
}
fn read_string(&mut self, length: u64) -> Result<String> {
let mut vec = vec![0u8; usize::try_from(length).context("String length too large for this platform")?];
self.get_reader().read_exact(&mut vec)?;
Ok(String::from_utf8(vec)?)
}
fn read_range(&mut self) -> Result<ByteRange> {
Ok(ByteRange::new(
self.get_reader().read_u64::<E>()?,
self.get_reader().read_u64::<E>()?,
))
}
fn read_pbf_key(&mut self) -> Result<(u32, u8)> {
let value = self.read_varint().context("Failed to read varint for PBF key")?;
let field_number = u32::try_from(value >> 3).context("PBF field number too large (exceeds u32::MAX)")?;
#[allow(clippy::cast_possible_truncation)]
let wire_type = (value & 0x07) as u8;
Ok((field_number, wire_type))
}
fn get_sub_reader<'b>(&'b mut self, length: u64) -> Result<Box<dyn ValueReader<'b, E> + 'b>>
where
E: 'b;
fn get_pbf_sub_reader<'b>(&'b mut self) -> Result<Box<dyn ValueReader<'b, E> + 'b>>
where
E: 'b,
{
let length = self
.read_varint()
.context("Failed to read varint for sub-reader length")?;
self.get_sub_reader(length).context("Failed to get sub-reader")
}
fn read_pbf_packed_uint32(&mut self) -> Result<Vec<u32>> {
let mut reader = self
.get_pbf_sub_reader()
.context("Failed to get PBF sub-reader for packed uint32")?;
let mut values = Vec::new();
while reader.has_remaining() {
values.push(
u32::try_from(
reader
.read_varint()
.context("Failed to read varint for packed uint32")?,
)
.context("Packed uint32 value too large (exceeds u32::MAX)")?,
);
}
drop(reader);
Ok(values)
}
fn read_pbf_string(&mut self) -> Result<String> {
let length = self.read_varint().context("Failed to read varint for string length")?;
self.read_string(length).context("Failed to read PBF string")
}
fn read_pbf_blob(&mut self) -> Result<Blob> {
let length = self.read_varint().context("Failed to read varint for blob length")?;
self.read_blob(length).context("Failed to read PBF blob")
}
}
#[cfg(test)]
#[allow(clippy::float_cmp)]
mod tests {
use super::super::ValueReaderSlice;
use super::*;
#[test]
fn test_is_empty() {
assert!(ValueReaderSlice::new_le(&[]).is_empty());
assert!(!ValueReaderSlice::new_le(&[0]).is_empty());
}
#[test]
fn test_read_varint() {
let mut reader = ValueReaderSlice::new_le(&[0xAC, 0x02]);
let value = reader.read_varint().unwrap();
assert_eq!(value, 300);
}
#[test]
fn test_read_svarint1() {
let mut reader = ValueReaderSlice::new_le(&[0x96, 0x01]);
assert_eq!(reader.read_svarint().unwrap(), 75);
}
#[test]
fn test_read_svarint2() {
let mut reader = ValueReaderSlice::new_le(&[0x95, 0x01]);
assert_eq!(reader.read_svarint().unwrap(), -75);
}
#[test]
fn test_read_f32_le() {
let mut reader = ValueReaderSlice::new_le(&[0, 0, 0x80, 0x3F]); assert_eq!(reader.read_f32().unwrap(), 1.0);
}
#[test]
fn test_read_f32_be() {
let mut reader = ValueReaderSlice::new_be(&[0x3F, 0x80, 0, 0]); assert_eq!(reader.read_f32().unwrap(), 1.0);
}
#[test]
fn test_read_f64_le() {
let mut reader = ValueReaderSlice::new_le(&[0, 0, 0, 0, 0, 0, 0xF0, 0x3F]); assert_eq!(reader.read_f64().unwrap(), 1.0);
}
#[test]
fn test_read_f64_be() {
let mut reader = ValueReaderSlice::new_be(&[0x3F, 0xF0, 0, 0, 0, 0, 0, 0]); assert_eq!(reader.read_f64().unwrap(), 1.0);
}
#[test]
fn test_read_u8() {
let mut reader = ValueReaderSlice::new_le(&[0xFF]);
assert_eq!(reader.read_u8().unwrap(), 255);
}
#[test]
fn test_read_i32() {
let mut reader = ValueReaderSlice::new_le(&[0xFF, 0xFF, 0xFF, 0xFF]); assert_eq!(reader.read_i32().unwrap(), -1);
}
#[test]
fn test_read_i64() {
let mut reader = ValueReaderSlice::new_le(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); assert_eq!(reader.read_i64().unwrap(), -1);
}
#[test]
fn test_read_u32() {
let mut reader = ValueReaderSlice::new_le(&[0xFF, 0xFF, 0xFF, 0xFF]); assert_eq!(reader.read_u32().unwrap(), 4_294_967_295);
}
#[test]
fn test_read_u64() {
let mut reader = ValueReaderSlice::new_le(&[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); assert_eq!(reader.read_u64().unwrap(), 18_446_744_073_709_551_615);
}
#[test]
fn test_read_blob() {
let data = vec![0x01, 0x02, 0x03, 0x04];
let mut reader = ValueReaderSlice::new_le(&data);
assert_eq!(reader.read_blob(3).unwrap().as_slice(), &data[0..3]);
}
#[test]
fn test_read_string() {
let mut reader = ValueReaderSlice::new_le(b"hello");
assert_eq!(reader.read_string(5).unwrap(), "hello");
}
#[test]
fn test_read_range() {
let mut reader = ValueReaderSlice::new_be(&[0, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0x02]);
let range = reader.read_range().unwrap();
assert_eq!(range.offset, 1);
assert_eq!(range.length, 2);
}
#[test]
fn test_read_pbf_key() {
let mut reader = ValueReaderSlice::new_le(&[0x08]);
let (field_number, wire_type) = reader.read_pbf_key().unwrap();
assert_eq!(field_number, 1);
assert_eq!(wire_type, 0);
}
#[test]
fn test_read_pbf_packed_uint32() {
let mut reader = ValueReaderSlice::new_le(&[0x05, 0x64, 0x96, 0x01, 0xAC, 0x02]);
assert_eq!(reader.read_pbf_packed_uint32().unwrap(), vec![100, 150, 300]);
}
#[test]
fn test_read_pbf_string() {
let mut reader = ValueReaderSlice::new_le(&[0x05, b'h', b'e', b'l', b'l', b'o']);
assert_eq!(reader.read_pbf_string().unwrap(), "hello");
}
#[test]
fn test_read_pbf_blob() {
let mut reader = ValueReaderSlice::new_le(&[0x03, 0x01, 0x02, 0x03]);
assert_eq!(reader.read_pbf_blob().unwrap().as_slice(), &[0x01, 0x02, 0x03]);
}
}