#[cfg(feature = "std")]
use std::fs::File;
#[cfg(feature = "std")]
use std::io::Read;
#[cfg(feature = "std")]
use std::path::Path;
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use crate::errors::{Error, Result};
use crate::message::MessageRead;
use byteorder::ByteOrder;
use byteorder::LittleEndian as LE;
const WIRE_TYPE_VARINT: u8 = 0;
const WIRE_TYPE_FIXED64: u8 = 1;
const WIRE_TYPE_LENGTH_DELIMITED: u8 = 2;
const WIRE_TYPE_START_GROUP: u8 = 3;
const WIRE_TYPE_END_GROUP: u8 = 4;
const WIRE_TYPE_FIXED32: u8 = 5;
#[derive(Debug, Clone, PartialEq)]
pub struct BytesReader {
start: usize,
end: usize,
}
impl BytesReader {
pub fn from_bytes(bytes: &[u8]) -> BytesReader {
BytesReader {
start: 0,
end: bytes.len(),
}
}
#[cfg_attr(std, inline(always))]
pub fn next_tag(&mut self, bytes: &[u8]) -> Result<u32> {
self.read_varint32(bytes)
}
#[cfg_attr(std, inline(always))]
pub fn read_u8(&mut self, bytes: &[u8]) -> Result<u8> {
let b = bytes.get(self.start).ok_or(Error::UnexpectedEndOfBuffer)?;
self.start += 1;
Ok(*b)
}
#[cfg_attr(std, inline(always))]
pub fn read_varint32(&mut self, bytes: &[u8]) -> Result<u32> {
let mut b = self.read_u8(bytes)?;
if b & 0x80 == 0 {
return Ok(b as u32);
}
let mut r = (b & 0x7f) as u32;
b = self.read_u8(bytes)?;
r |= ((b & 0x7f) as u32) << 7;
if b & 0x80 == 0 {
return Ok(r);
}
b = self.read_u8(bytes)?;
r |= ((b & 0x7f) as u32) << 14;
if b & 0x80 == 0 {
return Ok(r);
}
b = self.read_u8(bytes)?;
r |= ((b & 0x7f) as u32) << 21;
if b & 0x80 == 0 {
return Ok(r);
}
b = self.read_u8(bytes)?;
r |= ((b & 0xf) as u32) << 28;
if b & 0x80 == 0 {
return Ok(r);
}
for _ in 0..5 {
if self.read_u8(bytes)? & 0x80 == 0 {
return Ok(r);
}
}
Err(Error::Varint)
}
#[cfg_attr(std, inline(always))]
pub fn read_varint64(&mut self, bytes: &[u8]) -> Result<u64> {
let mut b = self.read_u8(bytes)?;
if b & 0x80 == 0 {
return Ok(b as u64);
}
let mut r0 = (b & 0x7f) as u32;
b = self.read_u8(bytes)?;
r0 |= ((b & 0x7f) as u32) << 7;
if b & 0x80 == 0 {
return Ok(r0 as u64);
}
b = self.read_u8(bytes)?;
r0 |= ((b & 0x7f) as u32) << 14;
if b & 0x80 == 0 {
return Ok(r0 as u64);
}
b = self.read_u8(bytes)?;
r0 |= ((b & 0x7f) as u32) << 21;
if b & 0x80 == 0 {
return Ok(r0 as u64);
}
b = self.read_u8(bytes)?;
let mut r1 = (b & 0x7f) as u32;
if b & 0x80 == 0 {
return Ok(r0 as u64 | (r1 as u64) << 28);
}
b = self.read_u8(bytes)?;
r1 |= ((b & 0x7f) as u32) << 7;
if b & 0x80 == 0 {
return Ok(r0 as u64 | (r1 as u64) << 28);
}
b = self.read_u8(bytes)?;
r1 |= ((b & 0x7f) as u32) << 14;
if b & 0x80 == 0 {
return Ok(r0 as u64 | (r1 as u64) << 28);
}
b = self.read_u8(bytes)?;
r1 |= ((b & 0x7f) as u32) << 21;
if b & 0x80 == 0 {
return Ok(r0 as u64 | (r1 as u64) << 28);
}
b = self.read_u8(bytes)?;
let mut r2 = (b & 0x7f) as u32;
if b & 0x80 == 0 {
return Ok((r0 as u64 | (r1 as u64) << 28) | (r2 as u64) << 56);
}
b = self.read_u8(bytes)?;
r2 |= (b as u32) << 7;
if b & 0x80 == 0 {
return Ok((r0 as u64 | (r1 as u64) << 28) | (r2 as u64) << 56);
}
Err(Error::Varint)
}
#[cfg_attr(std, inline)]
pub fn read_int32(&mut self, bytes: &[u8]) -> Result<i32> {
self.read_varint32(bytes).map(|i| i as i32)
}
#[cfg_attr(std, inline)]
pub fn read_int64(&mut self, bytes: &[u8]) -> Result<i64> {
self.read_varint64(bytes).map(|i| i as i64)
}
#[cfg_attr(std, inline)]
pub fn read_uint32(&mut self, bytes: &[u8]) -> Result<u32> {
self.read_varint32(bytes)
}
#[cfg_attr(std, inline)]
pub fn read_uint64(&mut self, bytes: &[u8]) -> Result<u64> {
self.read_varint64(bytes)
}
#[cfg_attr(std, inline)]
pub fn read_sint32(&mut self, bytes: &[u8]) -> Result<i32> {
let n = self.read_varint32(bytes)?;
Ok(((n >> 1) as i32) ^ (-((n & 1) as i32)))
}
#[cfg_attr(std, inline)]
pub fn read_sint64(&mut self, bytes: &[u8]) -> Result<i64> {
let n = self.read_varint64(bytes)?;
Ok(((n >> 1) as i64) ^ (-((n & 1) as i64)))
}
#[cfg_attr(std, inline)]
fn read_fixed<M, F: Fn(&[u8]) -> M>(&mut self, bytes: &[u8], len: usize, read: F) -> Result<M> {
let v = read(
&bytes
.get(self.start..self.start + len)
.ok_or_else(|| Error::UnexpectedEndOfBuffer)?,
);
self.start += len;
Ok(v)
}
#[cfg_attr(std, inline)]
pub fn read_fixed64(&mut self, bytes: &[u8]) -> Result<u64> {
self.read_fixed(bytes, 8, LE::read_u64)
}
#[cfg_attr(std, inline)]
pub fn read_fixed32(&mut self, bytes: &[u8]) -> Result<u32> {
self.read_fixed(bytes, 4, LE::read_u32)
}
#[cfg_attr(std, inline)]
pub fn read_sfixed64(&mut self, bytes: &[u8]) -> Result<i64> {
self.read_fixed(bytes, 8, LE::read_i64)
}
#[cfg_attr(std, inline)]
pub fn read_sfixed32(&mut self, bytes: &[u8]) -> Result<i32> {
self.read_fixed(bytes, 4, LE::read_i32)
}
#[cfg_attr(std, inline)]
pub fn read_float(&mut self, bytes: &[u8]) -> Result<f32> {
self.read_fixed(bytes, 4, LE::read_f32)
}
#[cfg_attr(std, inline)]
pub fn read_double(&mut self, bytes: &[u8]) -> Result<f64> {
self.read_fixed(bytes, 8, LE::read_f64)
}
#[cfg_attr(std, inline)]
pub fn read_bool(&mut self, bytes: &[u8]) -> Result<bool> {
self.read_varint32(bytes).map(|i| i != 0)
}
#[cfg_attr(std, inline)]
pub fn read_enum<E: From<i32>>(&mut self, bytes: &[u8]) -> Result<E> {
self.read_int32(bytes).map(|e| e.into())
}
#[cfg_attr(std, inline(always))]
fn read_len_varint<'a, M, F>(&mut self, bytes: &'a [u8], read: F) -> Result<M>
where
F: FnMut(&mut BytesReader, &'a [u8]) -> Result<M>,
{
let len = self.read_varint32(bytes)? as usize;
self.read_len(bytes, read, len)
}
#[cfg_attr(std, inline(always))]
fn read_len<'a, M, F>(&mut self, bytes: &'a [u8], mut read: F, len: usize) -> Result<M>
where
F: FnMut(&mut BytesReader, &'a [u8]) -> Result<M>,
{
let cur_end = self.end;
self.end = self.start + len;
let v = read(self, bytes)?;
self.start = self.end;
self.end = cur_end;
Ok(v)
}
#[cfg_attr(std, inline)]
pub fn read_bytes<'a>(&mut self, bytes: &'a [u8]) -> Result<&'a [u8]> {
self.read_len_varint(bytes, |r, b| {
b.get(r.start..r.end)
.ok_or_else(|| Error::UnexpectedEndOfBuffer)
})
}
#[cfg_attr(std, inline)]
pub fn read_string<'a>(&mut self, bytes: &'a [u8]) -> Result<&'a str> {
self.read_len_varint(bytes, |r, b| {
b.get(r.start..r.end)
.ok_or_else(|| Error::UnexpectedEndOfBuffer)
.and_then(|x| ::core::str::from_utf8(x).map_err(|e| e.into()))
})
}
#[cfg_attr(std, inline)]
pub fn read_packed<'a, M, F>(&mut self, bytes: &'a [u8], mut read: F) -> Result<Vec<M>>
where
F: FnMut(&mut BytesReader, &'a [u8]) -> Result<M>,
{
self.read_len_varint(bytes, |r, b| {
let mut v = Vec::new();
while !r.is_eof() {
v.push(read(r, b)?);
}
Ok(v)
})
}
#[cfg_attr(std, inline)]
pub fn read_packed_fixed<'a, M>(&mut self, bytes: &'a [u8]) -> Result<&'a [M]> {
let len = self.read_varint32(bytes)? as usize;
if self.len() < len {
return Err(Error::UnexpectedEndOfBuffer);
}
let n = len / ::core::mem::size_of::<M>();
let slice = unsafe {
::core::slice::from_raw_parts(
bytes.get_unchecked(self.start) as *const u8 as *const M,
n,
)
};
self.start += len;
Ok(slice)
}
#[cfg_attr(std, inline)]
pub fn read_message<'a, M>(&mut self, bytes: &'a [u8]) -> Result<M>
where
M: MessageRead<'a>,
{
self.read_len_varint(bytes, M::from_reader)
}
#[cfg_attr(std, inline)]
pub fn read_message_by_len<'a, M>(&mut self, bytes: &'a [u8], len: usize) -> Result<M>
where
M: MessageRead<'a>,
{
self.read_len(bytes, M::from_reader, len)
}
#[cfg_attr(std, inline)]
pub fn read_map<'a, K, V, F, G>(
&mut self,
bytes: &'a [u8],
mut read_key: F,
mut read_val: G,
) -> Result<(K, V)>
where
F: FnMut(&mut BytesReader, &'a [u8]) -> Result<K>,
G: FnMut(&mut BytesReader, &'a [u8]) -> Result<V>,
K: ::core::fmt::Debug + Default,
V: ::core::fmt::Debug + Default,
{
self.read_len_varint(bytes, |r, bytes| {
let mut k = K::default();
let mut v = V::default();
while !r.is_eof() {
let t = r.read_u8(bytes)?;
match t >> 3 {
1 => k = read_key(r, bytes)?,
2 => v = read_val(r, bytes)?,
t => return Err(Error::Map(t)),
}
}
Ok((k, v))
})
}
#[cfg_attr(std, inline)]
pub fn read_unknown(&mut self, bytes: &[u8], tag_value: u32) -> Result<()> {
match (tag_value & 0x7) as u8 {
WIRE_TYPE_VARINT => {
self.read_varint64(bytes)?;
}
WIRE_TYPE_FIXED64 => self.start += 8,
WIRE_TYPE_FIXED32 => self.start += 4,
WIRE_TYPE_LENGTH_DELIMITED => {
let len = self.read_varint64(bytes)? as usize;
self.start += len;
}
WIRE_TYPE_START_GROUP | WIRE_TYPE_END_GROUP => {
return Err(Error::Deprecated("group"));
}
t => {
return Err(Error::UnknownWireType(t));
}
}
Ok(())
}
#[cfg_attr(std, inline(always))]
pub fn len(&self) -> usize {
self.end - self.start
}
#[cfg_attr(std, inline(always))]
pub fn is_eof(&self) -> bool {
self.start == self.end
}
pub fn read_to_end(&mut self) {
self.start = self.end;
}
}
pub struct Reader {
buffer: Vec<u8>,
inner: BytesReader,
}
impl Reader {
#[cfg(feature = "std")]
pub fn from_reader<R: Read>(mut r: R, capacity: usize) -> Result<Reader> {
let mut buf = Vec::with_capacity(capacity);
unsafe {
buf.set_len(capacity);
}
buf.shrink_to_fit();
r.read_exact(&mut buf)?;
Ok(Reader::from_bytes(buf))
}
#[cfg(feature = "std")]
pub fn from_file<P: AsRef<Path>>(src: P) -> Result<Reader> {
let len = src.as_ref().metadata().unwrap().len() as usize;
let f = File::open(src)?;
Reader::from_reader(f, len)
}
pub fn from_bytes(bytes: Vec<u8>) -> Reader {
let reader = BytesReader {
start: 0,
end: bytes.len(),
};
Reader {
buffer: bytes,
inner: reader,
}
}
#[cfg_attr(std, inline)]
pub fn read<'a, M, F>(&'a mut self, mut read: F) -> Result<M>
where
F: FnMut(&mut BytesReader, &'a [u8]) -> Result<M>,
{
read(&mut self.inner, &self.buffer)
}
pub fn inner(&mut self) -> &mut BytesReader {
&mut self.inner
}
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
}
pub fn deserialize_from_slice<'a, M: MessageRead<'a>>(bytes: &'a [u8]) -> Result<M> {
let mut reader = BytesReader::from_bytes(&bytes);
reader.read_message::<M>(&bytes)
}
#[test]
fn test_varint() {
let data = [0x96, 0x01];
let mut r = BytesReader::from_bytes(&data[..]);
assert_eq!(150, r.read_varint32(&data[..]).unwrap());
assert!(r.is_eof());
}