mirror of
https://github.com/azalea-rs/simdnbt.git
synced 2025-08-02 07:26:04 +00:00
Optimize errors by using slimmer error types
This commit is contained in:
parent
4fa1f11f76
commit
b71d67e5b1
8 changed files with 134 additions and 62 deletions
|
@ -7,8 +7,9 @@ use crate::{
|
|||
DOUBLE_ID, END_ID, FLOAT_ID, INT_ARRAY_ID, INT_ID, LIST_ID, LONG_ARRAY_ID, LONG_ID,
|
||||
MAX_DEPTH, SHORT_ID, STRING_ID,
|
||||
},
|
||||
error::NonRootError,
|
||||
reader::Reader,
|
||||
Error, Mutf8Str,
|
||||
Mutf8Str,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -30,7 +31,7 @@ impl<'a: 'tape, 'tape> NbtCompound<'a, 'tape> {
|
|||
_data: &mut Reader<'a>,
|
||||
tapes: &'tape mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
let index_of_compound_element = tapes.main.len();
|
||||
|
||||
stack.push(ParsingStackElement::Compound {
|
||||
|
@ -255,12 +256,12 @@ impl ParsingStack {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn push(&mut self, state: ParsingStackElement) -> Result<(), Error> {
|
||||
pub fn push(&mut self, state: ParsingStackElement) -> Result<(), NonRootError> {
|
||||
unsafe { self.stack.get_unchecked_mut(self.depth).write(state) };
|
||||
self.depth += 1;
|
||||
|
||||
if self.depth >= MAX_DEPTH {
|
||||
Err(Error::MaxDepthExceeded)
|
||||
Err(NonRootError::max_depth_exceeded())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -327,7 +328,7 @@ pub(crate) fn read_tag<'a>(
|
|||
tapes: &mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
tag_type: u8,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
match tag_type {
|
||||
COMPOUND_ID => return NbtCompound::read(data, tapes, stack),
|
||||
LIST_ID => return NbtList::read(data, tapes, stack),
|
||||
|
@ -426,7 +427,7 @@ pub(crate) fn read_tag<'a>(
|
|||
),
|
||||
});
|
||||
}
|
||||
_ => return Err(Error::UnknownTagId(tag_type)),
|
||||
_ => return Err(NonRootError::unknown_tag_id(tag_type)),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
@ -436,7 +437,7 @@ pub(crate) fn read_tag_in_compound<'a>(
|
|||
data: &mut Reader<'a>,
|
||||
tapes: &mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
let tag_type = data.read_u8()?;
|
||||
if tag_type == END_ID {
|
||||
handle_compound_end(tapes, stack);
|
||||
|
|
|
@ -7,10 +7,11 @@ use crate::{
|
|||
BYTE_ARRAY_ID, BYTE_ID, COMPOUND_ID, DOUBLE_ID, END_ID, FLOAT_ID, INT_ARRAY_ID, INT_ID,
|
||||
LIST_ID, LONG_ARRAY_ID, LONG_ID, SHORT_ID, STRING_ID,
|
||||
},
|
||||
error::NonRootError,
|
||||
raw_list::RawList,
|
||||
reader::Reader,
|
||||
swap_endianness::SwappableNumber,
|
||||
Error, Mutf8Str,
|
||||
Mutf8Str,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
@ -31,7 +32,7 @@ impl<'a, 'tape> NbtList<'a, 'tape> {
|
|||
data: &mut Reader<'a>,
|
||||
tapes: &mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
let tag_type = data.read_u8()?;
|
||||
match tag_type {
|
||||
END_ID => {
|
||||
|
@ -221,7 +222,7 @@ impl<'a, 'tape> NbtList<'a, 'tape> {
|
|||
tapes.extra.elements.push(ExtraTapeElement { long_array });
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::UnknownTagId(tag_type)),
|
||||
_ => return Err(NonRootError::unknown_tag_id(tag_type)),
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
@ -867,7 +868,7 @@ pub fn read_list_in_list<'a>(
|
|||
data: &mut Reader<'a>,
|
||||
tapes: &mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
let ParsingStackElement::ListOfLists {
|
||||
index_of_list_element,
|
||||
} = stack.peek()
|
||||
|
@ -903,7 +904,7 @@ pub(crate) fn read_compound_in_list<'a>(
|
|||
data: &mut Reader<'a>,
|
||||
tapes: &mut Tapes<'a>,
|
||||
stack: &mut ParsingStack,
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), NonRootError> {
|
||||
let ParsingStackElement::ListOfCompounds {
|
||||
index_of_list_element,
|
||||
} = stack.peek()
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use std::{mem, slice};
|
||||
|
||||
use crate::{
|
||||
error::UnexpectedEofError,
|
||||
raw_list::RawList,
|
||||
reader::Reader,
|
||||
swap_endianness::{swap_endianness_as_u8, SwappableNumber},
|
||||
Error, Mutf8Str,
|
||||
Mutf8Str,
|
||||
};
|
||||
|
||||
pub const END_ID: u8 = 0;
|
||||
|
@ -24,37 +25,43 @@ pub const LONG_ARRAY_ID: u8 = 12;
|
|||
pub const MAX_DEPTH: usize = 512;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn read_with_u16_length<'a>(data: &mut Reader<'a>, width: usize) -> Result<&'a [u8], Error> {
|
||||
pub fn read_with_u16_length<'a>(
|
||||
data: &mut Reader<'a>,
|
||||
width: usize,
|
||||
) -> Result<&'a [u8], UnexpectedEofError> {
|
||||
let length = data.read_u16()?;
|
||||
let length_in_bytes = length as usize * width;
|
||||
data.read_slice(length_in_bytes)
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn read_with_u32_length<'a>(data: &mut Reader<'a>, width: usize) -> Result<&'a [u8], Error> {
|
||||
pub fn read_with_u32_length<'a>(
|
||||
data: &mut Reader<'a>,
|
||||
width: usize,
|
||||
) -> Result<&'a [u8], UnexpectedEofError> {
|
||||
let length = data.read_u32()?;
|
||||
let length_in_bytes = length as usize * width;
|
||||
data.read_slice(length_in_bytes)
|
||||
}
|
||||
|
||||
pub fn read_string<'a>(data: &mut Reader<'a>) -> Result<&'a Mutf8Str, Error> {
|
||||
pub fn read_string<'a>(data: &mut Reader<'a>) -> Result<&'a Mutf8Str, UnexpectedEofError> {
|
||||
let data = read_with_u16_length(data, 1)?;
|
||||
Ok(Mutf8Str::from_slice(data))
|
||||
}
|
||||
|
||||
pub fn read_u8_array<'a>(data: &mut Reader<'a>) -> Result<&'a [u8], Error> {
|
||||
pub fn read_u8_array<'a>(data: &mut Reader<'a>) -> Result<&'a [u8], UnexpectedEofError> {
|
||||
read_with_u32_length(data, 1)
|
||||
}
|
||||
pub fn read_i8_array<'a>(data: &mut Reader<'a>) -> Result<&'a [i8], Error> {
|
||||
pub fn read_i8_array<'a>(data: &mut Reader<'a>) -> Result<&'a [i8], UnexpectedEofError> {
|
||||
Ok(slice_u8_into_i8(read_u8_array(data)?))
|
||||
}
|
||||
|
||||
pub fn read_int_array<'a>(data: &mut Reader<'a>) -> Result<RawList<'a, i32>, Error> {
|
||||
pub fn read_int_array<'a>(data: &mut Reader<'a>) -> Result<RawList<'a, i32>, UnexpectedEofError> {
|
||||
let array_bytes = read_with_u32_length(data, 4)?;
|
||||
Ok(RawList::new(array_bytes))
|
||||
}
|
||||
|
||||
pub fn read_long_array<'a>(data: &mut Reader<'a>) -> Result<RawList<'a, i64>, Error> {
|
||||
pub fn read_long_array<'a>(data: &mut Reader<'a>) -> Result<RawList<'a, i64>, UnexpectedEofError> {
|
||||
let array_bytes = read_with_u32_length(data, 8)?;
|
||||
Ok(RawList::new(array_bytes))
|
||||
}
|
||||
|
|
|
@ -14,6 +14,55 @@ pub enum Error {
|
|||
MaxDepthExceeded,
|
||||
}
|
||||
|
||||
// these two structs exist to optimize errors, since Error is an entire 2 bytes
|
||||
// which are often unnecessary
|
||||
pub(crate) struct UnexpectedEofError;
|
||||
impl From<UnexpectedEofError> for Error {
|
||||
fn from(_: UnexpectedEofError) -> Self {
|
||||
Error::UnexpectedEof
|
||||
}
|
||||
}
|
||||
pub struct NonRootError {
|
||||
// 0 = unexpected eof
|
||||
// 1 = max depth exceeded
|
||||
// anything else = unknown tag id, the id is value-1
|
||||
value: u8,
|
||||
}
|
||||
impl From<NonRootError> for Error {
|
||||
#[inline]
|
||||
fn from(e: NonRootError) -> Self {
|
||||
match e.value {
|
||||
0 => Error::UnexpectedEof,
|
||||
1 => Error::MaxDepthExceeded,
|
||||
_ => Error::UnknownTagId(e.value.wrapping_add(1)),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl NonRootError {
|
||||
#[inline]
|
||||
pub fn unexpected_eof() -> Self {
|
||||
NonRootError { value: 0 }
|
||||
}
|
||||
#[inline]
|
||||
pub fn max_depth_exceeded() -> Self {
|
||||
NonRootError { value: 1 }
|
||||
}
|
||||
#[inline]
|
||||
pub fn unknown_tag_id(id: u8) -> Self {
|
||||
// the value can't be 1 or 2 (because those are always valid tag ids),
|
||||
// so we take advantage of that in our encoding
|
||||
NonRootError {
|
||||
value: id.wrapping_sub(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<UnexpectedEofError> for NonRootError {
|
||||
#[inline]
|
||||
fn from(_: UnexpectedEofError) -> Self {
|
||||
NonRootError::unexpected_eof()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DeserializeError {
|
||||
#[error("Missing field")]
|
||||
|
|
|
@ -2,9 +2,10 @@ use std::mem::{self, MaybeUninit};
|
|||
|
||||
use crate::{
|
||||
common::{read_string, unchecked_push, unchecked_write_string, END_ID, MAX_DEPTH},
|
||||
error::NonRootError,
|
||||
mutf8::Mutf8String,
|
||||
reader::Reader,
|
||||
Error, Mutf8Str, ToNbtTag,
|
||||
Mutf8Str, ToNbtTag,
|
||||
};
|
||||
|
||||
use super::{list::NbtList, NbtTag};
|
||||
|
@ -24,7 +25,7 @@ impl NbtCompound {
|
|||
Self { values }
|
||||
}
|
||||
|
||||
pub(crate) fn read(data: &mut Reader<'_>) -> Result<Self, Error> {
|
||||
pub(crate) fn read(data: &mut Reader<'_>) -> Result<Self, NonRootError> {
|
||||
Self::read_with_depth(data, 0)
|
||||
}
|
||||
|
||||
|
@ -32,9 +33,9 @@ impl NbtCompound {
|
|||
data: &mut Reader<'_>,
|
||||
depth: usize,
|
||||
capacity: usize,
|
||||
) -> Result<Self, Error> {
|
||||
) -> Result<Self, NonRootError> {
|
||||
if depth > MAX_DEPTH {
|
||||
return Err(Error::MaxDepthExceeded);
|
||||
return Err(NonRootError::max_depth_exceeded());
|
||||
}
|
||||
|
||||
let mut tags_buffer = unsafe {
|
||||
|
@ -44,7 +45,7 @@ impl NbtCompound {
|
|||
|
||||
let mut values = Vec::with_capacity(capacity);
|
||||
loop {
|
||||
let tag_type = data.read_u8().map_err(|_| Error::UnexpectedEof)?;
|
||||
let tag_type = data.read_u8().map_err(|_| NonRootError::unexpected_eof())?;
|
||||
if tag_type == END_ID {
|
||||
break;
|
||||
}
|
||||
|
@ -69,7 +70,10 @@ impl NbtCompound {
|
|||
Ok(Self { values })
|
||||
}
|
||||
|
||||
pub(crate) fn read_with_depth(data: &mut Reader<'_>, depth: usize) -> Result<Self, Error> {
|
||||
pub(crate) fn read_with_depth(
|
||||
data: &mut Reader<'_>,
|
||||
depth: usize,
|
||||
) -> Result<Self, NonRootError> {
|
||||
Self::read_with_depth_and_capacity(data, depth, 8)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ use crate::{
|
|||
COMPOUND_ID, DOUBLE_ID, END_ID, FLOAT_ID, INT_ARRAY_ID, INT_ID, LIST_ID, LONG_ARRAY_ID,
|
||||
LONG_ID, SHORT_ID, STRING_ID,
|
||||
},
|
||||
error::NonRootError,
|
||||
mutf8::Mutf8String,
|
||||
reader::Reader,
|
||||
swap_endianness::swap_endianness,
|
||||
Error,
|
||||
};
|
||||
|
||||
use super::{compound::NbtCompound, MAX_DEPTH};
|
||||
|
@ -34,11 +34,11 @@ pub enum NbtList {
|
|||
LongArray(Vec<Vec<i64>>) = LONG_ARRAY_ID,
|
||||
}
|
||||
impl NbtList {
|
||||
pub(crate) fn read(data: &mut Reader<'_>, depth: usize) -> Result<Self, Error> {
|
||||
pub(crate) fn read(data: &mut Reader<'_>, depth: usize) -> Result<Self, NonRootError> {
|
||||
if depth > MAX_DEPTH {
|
||||
return Err(Error::MaxDepthExceeded);
|
||||
return Err(NonRootError::max_depth_exceeded());
|
||||
}
|
||||
let tag_type = data.read_u8().map_err(|_| Error::UnexpectedEof)?;
|
||||
let tag_type = data.read_u8().map_err(|_| NonRootError::unexpected_eof())?;
|
||||
Ok(match tag_type {
|
||||
END_ID => {
|
||||
data.skip(4)?;
|
||||
|
@ -107,7 +107,7 @@ impl NbtList {
|
|||
}
|
||||
arrays
|
||||
}),
|
||||
_ => return Err(Error::UnknownTagId(tag_type)),
|
||||
_ => return Err(NonRootError::unknown_tag_id(tag_type)),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::{
|
|||
BYTE_ID, COMPOUND_ID, DOUBLE_ID, END_ID, FLOAT_ID, INT_ARRAY_ID, INT_ID, LIST_ID,
|
||||
LONG_ARRAY_ID, LONG_ID, MAX_DEPTH, SHORT_ID, STRING_ID,
|
||||
},
|
||||
error::NonRootError,
|
||||
mutf8::Mutf8String,
|
||||
reader::{Reader, ReaderFromCursor},
|
||||
Error, Mutf8Str,
|
||||
|
@ -37,20 +38,20 @@ pub fn read_unnamed(data: &mut Cursor<&[u8]>) -> Result<Nbt, Error> {
|
|||
Nbt::read_unnamed(&mut reader)
|
||||
}
|
||||
/// Read a compound tag. This may have any number of items.
|
||||
pub fn read_compound(data: &mut Cursor<&[u8]>) -> Result<NbtCompound, Error> {
|
||||
pub fn read_compound(data: &mut Cursor<&[u8]>) -> Result<NbtCompound, NonRootError> {
|
||||
let mut reader = ReaderFromCursor::new(data);
|
||||
NbtCompound::read(&mut reader)
|
||||
}
|
||||
/// Read an NBT tag, without reading its name. This may be any type of tag except for an end tag. If you need to be able to
|
||||
/// handle end tags, use [`read_optional_tag`].
|
||||
pub fn read_tag(data: &mut Cursor<&[u8]>) -> Result<NbtTag, Error> {
|
||||
pub fn read_tag(data: &mut Cursor<&[u8]>) -> Result<NbtTag, NonRootError> {
|
||||
let mut reader = ReaderFromCursor::new(data);
|
||||
NbtTag::read(&mut reader)
|
||||
}
|
||||
/// Read any NBT tag, without reading its name. This may be any type of tag, including an end tag.
|
||||
///
|
||||
/// Returns `Ok(None)` if there is no data.
|
||||
pub fn read_optional_tag(data: &mut Cursor<&[u8]>) -> Result<Option<NbtTag>, Error> {
|
||||
pub fn read_optional_tag(data: &mut Cursor<&[u8]>) -> Result<Option<NbtTag>, NonRootError> {
|
||||
let mut reader = ReaderFromCursor::new(data);
|
||||
NbtTag::read_optional(&mut reader)
|
||||
}
|
||||
|
@ -262,25 +263,34 @@ impl NbtTag {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read_with_type(data: &mut Reader<'_>, tag_type: u8, depth: usize) -> Result<Self, Error> {
|
||||
fn read_with_type(
|
||||
data: &mut Reader<'_>,
|
||||
tag_type: u8,
|
||||
depth: usize,
|
||||
) -> Result<Self, NonRootError> {
|
||||
match tag_type {
|
||||
BYTE_ID => Ok(NbtTag::Byte(
|
||||
data.read_i8().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_i8().map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
SHORT_ID => Ok(NbtTag::Short(
|
||||
data.read_i16().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_i16()
|
||||
.map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
INT_ID => Ok(NbtTag::Int(
|
||||
data.read_i32().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_i32()
|
||||
.map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
LONG_ID => Ok(NbtTag::Long(
|
||||
data.read_i64().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_i64()
|
||||
.map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
FLOAT_ID => Ok(NbtTag::Float(
|
||||
data.read_f32().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_f32()
|
||||
.map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
DOUBLE_ID => Ok(NbtTag::Double(
|
||||
data.read_f64().map_err(|_| Error::UnexpectedEof)?,
|
||||
data.read_f64()
|
||||
.map_err(|_| NonRootError::unexpected_eof())?,
|
||||
)),
|
||||
BYTE_ARRAY_ID => Ok(NbtTag::ByteArray(read_with_u32_length(data, 1)?.to_owned())),
|
||||
STRING_ID => Ok(NbtTag::String(read_string(data)?.to_owned())),
|
||||
|
@ -291,17 +301,17 @@ impl NbtTag {
|
|||
)?)),
|
||||
INT_ARRAY_ID => Ok(NbtTag::IntArray(read_int_array(data)?.to_vec())),
|
||||
LONG_ARRAY_ID => Ok(NbtTag::LongArray(read_long_array(data)?.to_vec())),
|
||||
_ => Err(Error::UnknownTagId(tag_type)),
|
||||
_ => Err(NonRootError::unknown_tag_id(tag_type)),
|
||||
}
|
||||
}
|
||||
|
||||
fn read(data: &mut Reader<'_>) -> Result<Self, Error> {
|
||||
let tag_type = data.read_u8().map_err(|_| Error::UnexpectedEof)?;
|
||||
fn read(data: &mut Reader<'_>) -> Result<Self, NonRootError> {
|
||||
let tag_type = data.read_u8().map_err(|_| NonRootError::unexpected_eof())?;
|
||||
Self::read_with_type(data, tag_type, 0)
|
||||
}
|
||||
|
||||
fn read_optional(data: &mut Reader<'_>) -> Result<Option<Self>, Error> {
|
||||
let tag_type = data.read_u8().map_err(|_| Error::UnexpectedEof)?;
|
||||
fn read_optional(data: &mut Reader<'_>) -> Result<Option<Self>, NonRootError> {
|
||||
let tag_type = data.read_u8().map_err(|_| NonRootError::unexpected_eof())?;
|
||||
if tag_type == END_ID {
|
||||
return Ok(None);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
use crate::Error;
|
||||
use crate::error::UnexpectedEofError;
|
||||
|
||||
pub struct Reader<'a> {
|
||||
pub cur: *const u8,
|
||||
|
@ -23,11 +23,11 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn ensure_can_read(&self, size: usize) -> Result<(), Error> {
|
||||
pub fn ensure_can_read(&self, size: usize) -> Result<(), UnexpectedEofError> {
|
||||
let data_addr = self.cur as usize;
|
||||
let end_addr = self.end as usize;
|
||||
if data_addr + size > end_addr {
|
||||
Err(Error::UnexpectedEof)
|
||||
Err(UnexpectedEofError)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -39,75 +39,75 @@ impl<'a> Reader<'a> {
|
|||
value
|
||||
}
|
||||
|
||||
pub fn read_type<T: Copy>(&mut self) -> Result<T, Error> {
|
||||
pub fn read_type<T: Copy>(&mut self) -> Result<T, UnexpectedEofError> {
|
||||
self.ensure_can_read(std::mem::size_of::<T>())?;
|
||||
Ok(unsafe { self.unchecked_read_type() })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u8(&mut self) -> Result<u8, Error> {
|
||||
pub fn read_u8(&mut self) -> Result<u8, UnexpectedEofError> {
|
||||
self.read_type()
|
||||
}
|
||||
#[inline]
|
||||
pub fn read_i8(&mut self) -> Result<i8, Error> {
|
||||
pub fn read_i8(&mut self) -> Result<i8, UnexpectedEofError> {
|
||||
self.read_u8().map(|x| x as i8)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u16(&mut self) -> Result<u16, Error> {
|
||||
pub fn read_u16(&mut self) -> Result<u16, UnexpectedEofError> {
|
||||
let value = self.read_type::<u16>();
|
||||
#[cfg(target_endian = "little")]
|
||||
let value = value.map(u16::swap_bytes);
|
||||
value
|
||||
}
|
||||
#[inline]
|
||||
pub fn read_i16(&mut self) -> Result<i16, Error> {
|
||||
pub fn read_i16(&mut self) -> Result<i16, UnexpectedEofError> {
|
||||
self.read_u16().map(|x| x as i16)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u32(&mut self) -> Result<u32, Error> {
|
||||
pub fn read_u32(&mut self) -> Result<u32, UnexpectedEofError> {
|
||||
let value = self.read_type::<u32>();
|
||||
#[cfg(target_endian = "little")]
|
||||
let value = value.map(u32::swap_bytes);
|
||||
value
|
||||
}
|
||||
#[inline]
|
||||
pub fn read_i32(&mut self) -> Result<i32, Error> {
|
||||
pub fn read_i32(&mut self) -> Result<i32, UnexpectedEofError> {
|
||||
self.read_u32().map(|x| x as i32)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_u64(&mut self) -> Result<u64, Error> {
|
||||
pub fn read_u64(&mut self) -> Result<u64, UnexpectedEofError> {
|
||||
let value = self.read_type::<u64>();
|
||||
#[cfg(target_endian = "little")]
|
||||
let value = value.map(u64::swap_bytes);
|
||||
value
|
||||
}
|
||||
#[inline]
|
||||
pub fn read_i64(&mut self) -> Result<i64, Error> {
|
||||
pub fn read_i64(&mut self) -> Result<i64, UnexpectedEofError> {
|
||||
self.read_u64().map(|x| x as i64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_f32(&mut self) -> Result<f32, Error> {
|
||||
pub fn read_f32(&mut self) -> Result<f32, UnexpectedEofError> {
|
||||
self.read_u32().map(f32::from_bits)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_f64(&mut self) -> Result<f64, Error> {
|
||||
pub fn read_f64(&mut self) -> Result<f64, UnexpectedEofError> {
|
||||
self.read_u64().map(f64::from_bits)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn skip(&mut self, size: usize) -> Result<(), Error> {
|
||||
pub fn skip(&mut self, size: usize) -> Result<(), UnexpectedEofError> {
|
||||
self.ensure_can_read(size)?;
|
||||
self.cur = unsafe { self.cur.add(size) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_slice(&mut self, size: usize) -> Result<&'a [u8], Error> {
|
||||
pub fn read_slice(&mut self, size: usize) -> Result<&'a [u8], UnexpectedEofError> {
|
||||
self.ensure_can_read(size)?;
|
||||
let slice = unsafe { std::slice::from_raw_parts(self.cur, size) };
|
||||
self.cur = unsafe { self.cur.add(size) };
|
||||
|
|
Loading…
Add table
Reference in a new issue