mirror of
https://github.com/azalea-rs/simdnbt.git
synced 2025-08-02 07:26:04 +00:00
optimized reading tag name in read_tag_in_compound
This commit is contained in:
parent
c9e8ebe341
commit
acb56cd97a
5 changed files with 39 additions and 30 deletions
|
@ -3,9 +3,9 @@ use std::mem::MaybeUninit;
|
|||
use crate::{
|
||||
common::{
|
||||
extend_unchecked, push_unchecked, read_int_array, read_long_array, read_string,
|
||||
read_with_u32_length, skip_string, write_string, write_string_unchecked, 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, MAX_DEPTH, SHORT_ID, STRING_ID,
|
||||
read_with_u32_length, write_string, write_string_unchecked, 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, MAX_DEPTH, SHORT_ID, STRING_ID,
|
||||
},
|
||||
error::NonRootError,
|
||||
reader::Reader,
|
||||
|
@ -237,7 +237,7 @@ pub(crate) struct ParsingStackElement {
|
|||
pub kind: ParsingStackElementKind,
|
||||
pub index: u32,
|
||||
}
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[repr(u32)]
|
||||
pub(crate) enum ParsingStackElementKind {
|
||||
Compound,
|
||||
|
@ -413,7 +413,7 @@ pub(crate) fn read_tag<'a>(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[inline]
|
||||
pub(crate) fn read_tag_in_compound<'a>(
|
||||
data: &mut Reader<'a>,
|
||||
tapes: &mut Tapes<'a>,
|
||||
|
@ -427,7 +427,27 @@ pub(crate) fn read_tag_in_compound<'a>(
|
|||
|
||||
let tag_name_ptr = data.cur;
|
||||
debug_assert_eq!(tag_name_ptr as u64 >> 56, 0);
|
||||
skip_string(data)?;
|
||||
|
||||
// read the string in a more efficient way than just calling read_string
|
||||
|
||||
let mut cur_addr = tag_name_ptr as usize;
|
||||
let end_addr = data.end_addr();
|
||||
cur_addr += 2;
|
||||
if cur_addr > end_addr {
|
||||
return Err(NonRootError::unexpected_eof());
|
||||
}
|
||||
// this actually results in an extra instruction since it sets the data.cur
|
||||
// unnecessarily, but for some reason it's faster anyways
|
||||
let length = unsafe { data.read_type_unchecked::<u16>() }.to_be();
|
||||
let length_in_bytes: usize = length as usize;
|
||||
cur_addr += length_in_bytes;
|
||||
if cur_addr > end_addr {
|
||||
return Err(NonRootError::unexpected_eof());
|
||||
}
|
||||
data.cur = cur_addr as *const u8;
|
||||
|
||||
// finished reading the string
|
||||
|
||||
tapes.main.push(TapeElement::new(tag_name_ptr as u64));
|
||||
|
||||
read_tag(data, tapes, stack, tag_type)
|
||||
|
|
|
@ -34,6 +34,7 @@ impl<'a, 'tape> NbtList<'a, 'tape> {
|
|||
stack: &mut ParsingStack,
|
||||
) -> Result<(), NonRootError> {
|
||||
let tag_type = data.read_u8()?;
|
||||
|
||||
let pushing_element = match tag_type {
|
||||
END_ID => {
|
||||
// the length is unused for this type of lists
|
||||
|
|
|
@ -49,25 +49,6 @@ pub fn read_string<'a>(data: &mut Reader<'a>) -> Result<&'a Mutf8Str, Unexpected
|
|||
Ok(Mutf8Str::from_slice(data))
|
||||
}
|
||||
|
||||
pub fn skip_string(data: &mut Reader<'_>) -> Result<(), UnexpectedEofError> {
|
||||
let cur_addr = data.cur_addr();
|
||||
let end_addr = data.end_addr();
|
||||
|
||||
if cur_addr + 2 > end_addr {
|
||||
return Err(UnexpectedEofError);
|
||||
}
|
||||
|
||||
let length = unsafe { data.read_type_unchecked::<u16>() }.to_be();
|
||||
let length_in_bytes: usize = length as usize;
|
||||
if cur_addr + 2 + length_in_bytes > end_addr {
|
||||
return Err(UnexpectedEofError);
|
||||
}
|
||||
|
||||
unsafe { data.skip_unchecked(length_in_bytes) };
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_u8_array<'a>(data: &mut Reader<'a>) -> Result<&'a [u8], UnexpectedEofError> {
|
||||
read_with_u32_length(data, 1)
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ impl Mutf8String {
|
|||
Mutf8Str::from_slice(self.vec.as_slice())
|
||||
}
|
||||
|
||||
/// Try to convert this MUTF-8 string into a UTF-8 string. If the data isn't
|
||||
/// Convert this MUTF-8 string into a UTF-8 string. If the data isn't
|
||||
/// valid MUTF-8, it'll return an empty string without erroring.
|
||||
#[inline]
|
||||
pub fn into_string(self) -> String {
|
||||
|
@ -193,6 +193,17 @@ impl Mutf8String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Try to convert this MUTF-8 string into a UTF-8 string.
|
||||
#[inline]
|
||||
pub fn try_into_string(self) -> Result<String, simd_cesu8::DecodingError> {
|
||||
if is_plain_ascii(&self.vec) {
|
||||
// SAFETY: &[u8] and &str are the same layout.
|
||||
Ok(unsafe { String::from_utf8_unchecked(self.vec) })
|
||||
} else {
|
||||
mutf8::decode(&self.vec).map(|cow| cow.into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_string(s: String) -> Mutf8String {
|
||||
Self::from_vec(mutf8::encode(&s).into_owned())
|
||||
|
|
|
@ -24,10 +24,6 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cur_addr(&self) -> usize {
|
||||
self.cur as usize
|
||||
}
|
||||
#[inline]
|
||||
pub fn end_addr(&self) -> usize {
|
||||
self.end as usize
|
||||
|
|
Loading…
Add table
Reference in a new issue