mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +02:00
optimize dynamic length string reading
This commit is contained in:
parent
c571326ed7
commit
8fdcd6b4c4
1 changed files with 25 additions and 12 deletions
|
|
@ -294,7 +294,7 @@ where
|
||||||
let usable_bytes = if E::is_le() {
|
let usable_bytes = if E::is_le() {
|
||||||
&bytes[0..read]
|
&bytes[0..read]
|
||||||
} else {
|
} else {
|
||||||
&bytes[8 - read..8]
|
&bytes[USIZE_SIZE - read..USIZE_SIZE]
|
||||||
};
|
};
|
||||||
data.extend_from_slice(usable_bytes);
|
data.extend_from_slice(usable_bytes);
|
||||||
byte_left -= read;
|
byte_left -= read;
|
||||||
|
|
@ -340,26 +340,39 @@ where
|
||||||
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
/// [`ReadError::NotEnoughData`]: enum.ReadError.html#variant.NotEnoughData
|
||||||
/// [`ReadError::Utf8Error`]: enum.ReadError.html#variant.Utf8Error
|
/// [`ReadError::Utf8Error`]: enum.ReadError.html#variant.Utf8Error
|
||||||
pub fn read_string(&self, position: usize, byte_len: Option<usize>) -> Result<String> {
|
pub fn read_string(&self, position: usize, byte_len: Option<usize>) -> Result<String> {
|
||||||
let bytes = match byte_len {
|
let bytes = self.read_string_bytes(position, byte_len)?;
|
||||||
Some(len) => self.read_bytes(position, len)?,
|
|
||||||
None => {
|
|
||||||
let mut acc = vec![];
|
|
||||||
let mut pos = position;
|
|
||||||
loop {
|
|
||||||
let byte = self.read_int(pos, 8)?;
|
|
||||||
acc.push(byte);
|
|
||||||
if byte == 0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pos += 8;
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let raw_string = String::from_utf8(bytes)?;
|
let raw_string = String::from_utf8(bytes)?;
|
||||||
Ok(raw_string.trim_end_matches(char::from(0)).to_owned())
|
Ok(raw_string.trim_end_matches(char::from(0)).to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_string_bytes(&self, position: usize, byte_len: Option<usize>) -> Result<Vec<u8>> {
|
||||||
|
match byte_len {
|
||||||
|
Some(len) => return self.read_bytes(position, len),
|
||||||
|
None => {
|
||||||
|
let mut acc = Vec::with_capacity(25);
|
||||||
|
let mut pos = position;
|
||||||
|
loop {
|
||||||
|
let read = min((USIZE_SIZE - 1) * 8, self.bit_len - pos);
|
||||||
|
let raw_bytes = self.read_usize(pos, read)?;
|
||||||
|
let bytes: [u8; USIZE_SIZE] = if E::is_le() {
|
||||||
|
raw_bytes.to_le_bytes()
|
||||||
|
} else {
|
||||||
|
raw_bytes.to_be_bytes()
|
||||||
|
};
|
||||||
|
for i in 0..(USIZE_SIZE - 1) {
|
||||||
|
let byte = if E::is_le() { bytes[i] } else { bytes[1 + i] };
|
||||||
|
|
||||||
|
if byte == 0 {
|
||||||
|
return Ok(acc);
|
||||||
|
}
|
||||||
|
acc.push(byte);
|
||||||
|
}
|
||||||
|
pos += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Read a sequence of bits from the buffer as float
|
/// Read a sequence of bits from the buffer as float
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue