fix lzma
This commit is contained in:
parent
9ac5ff7186
commit
95b31125fc
16 changed files with 143 additions and 88 deletions
|
|
@ -73,10 +73,10 @@ impl TryFrom<BitmapCommand> for Packet {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for BitmapCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let code = CommandCode::try_from(header.command_code)?;
|
||||
let compression = BitmapCommand::compression_for_command_code(code)
|
||||
.ok_or(InvalidCommandCodeError(header.command_code))?;
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ use std::fmt::Debug;
|
|||
pub struct BitmapLegacyCommand;
|
||||
|
||||
impl LoadableFromPacket for BitmapLegacyCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
_: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
check_command_code_only(header, CommandCode::BitmapLegacy)?;
|
||||
Ok((Self, 0))
|
||||
Ok((Self, payload))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,10 +81,10 @@ impl TryFrom<&BitVecCommand> for Packet {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for BitVecCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let Header {
|
||||
command_code,
|
||||
a: offset,
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@ impl From<BrightnessGrid> for BrightnessGridCommand {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for BrightnessGridCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let Header {
|
||||
command_code,
|
||||
a: x,
|
||||
|
|
@ -70,10 +70,11 @@ impl LoadableFromPacket for BrightnessGridCommand {
|
|||
});
|
||||
};
|
||||
|
||||
let (payload, remaining) = payload.split_at(expected_size);
|
||||
let grid = ByteGrid::from_raw_parts_unchecked(
|
||||
width as usize,
|
||||
height as usize,
|
||||
payload[..expected_size].to_vec(),
|
||||
payload.to_vec(),
|
||||
);
|
||||
let grid = match BrightnessGrid::try_from(grid) {
|
||||
Ok(grid) => grid,
|
||||
|
|
@ -85,7 +86,7 @@ impl LoadableFromPacket for BrightnessGridCommand {
|
|||
grid,
|
||||
origin: Origin::new(x as usize, y as usize),
|
||||
},
|
||||
expected_size,
|
||||
remaining,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ impl TryFrom<&CharGridCommand> for Packet {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for CharGridCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let Header {
|
||||
command_code,
|
||||
a: origin_x,
|
||||
|
|
@ -72,9 +72,9 @@ impl LoadableFromPacket for CharGridCommand {
|
|||
}
|
||||
|
||||
// TODO this does not work as char != byte
|
||||
let payload = String::from_utf8(payload[..expected].to_vec())?
|
||||
.chars()
|
||||
.collect();
|
||||
let (payload, remaining) = payload.split_at(expected);
|
||||
|
||||
let payload = String::from_utf8(payload.to_vec())?.chars().collect();
|
||||
Ok((
|
||||
Self {
|
||||
origin: Origin::new(origin_x as usize, origin_y as usize),
|
||||
|
|
@ -84,7 +84,7 @@ impl LoadableFromPacket for CharGridCommand {
|
|||
payload,
|
||||
),
|
||||
},
|
||||
expected,
|
||||
remaining,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,12 +18,12 @@ use std::fmt::Debug;
|
|||
pub struct ClearCommand;
|
||||
|
||||
impl LoadableFromPacket for ClearCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
_: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
check_command_code_only(header, CommandCode::Clear)?;
|
||||
Ok((Self, 0))
|
||||
Ok((Self, payload))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ impl TryFrom<&Cp437GridCommand> for Packet {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for Cp437GridCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let Header {
|
||||
command_code,
|
||||
a: origin_x,
|
||||
|
|
@ -84,6 +84,8 @@ impl LoadableFromPacket for Cp437GridCommand {
|
|||
});
|
||||
}
|
||||
|
||||
let (payload, remaining) = payload.split_at(expected);
|
||||
|
||||
Ok((
|
||||
Self {
|
||||
origin: Origin::new(origin_x as usize, origin_y as usize),
|
||||
|
|
@ -93,7 +95,7 @@ impl LoadableFromPacket for Cp437GridCommand {
|
|||
Vec::from(&payload[..expected]),
|
||||
),
|
||||
},
|
||||
expected,
|
||||
remaining,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ use std::fmt::Debug;
|
|||
pub struct FadeOutCommand;
|
||||
|
||||
impl LoadableFromPacket for FadeOutCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
_: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
check_command_code_only(header, CommandCode::FadeOut)?;
|
||||
Ok((Self, 0))
|
||||
Ok((Self, payload))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ impl From<&GlobalBrightnessCommand> for Packet {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for GlobalBrightnessCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let Header {
|
||||
command_code,
|
||||
a,
|
||||
|
|
@ -67,9 +67,11 @@ impl LoadableFromPacket for GlobalBrightnessCommand {
|
|||
},
|
||||
)?;
|
||||
|
||||
let (_, remaining) = payload.split_at(1);
|
||||
|
||||
let brightness = Brightness::try_from(brightness)
|
||||
.map_err(|_| TryFromPacketError::InvalidBrightness(brightness))?;
|
||||
Ok((Self { brightness }, 1))
|
||||
Ok((Self { brightness }, remaining))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ use std::fmt::Debug;
|
|||
pub struct HardResetCommand;
|
||||
|
||||
impl LoadableFromPacket for HardResetCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
_: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
check_command_code_only(header, CommandCode::HardReset)?;
|
||||
Ok((Self, 0))
|
||||
Ok((Self, payload))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,24 +99,26 @@ impl<
|
|||
{
|
||||
}
|
||||
|
||||
/// Similar to [`TryFrom<Packet>`].
|
||||
pub trait LoadableFromPacket: Sized {
|
||||
/// Load the specified header and payload.
|
||||
///
|
||||
/// In case of success, returns a tuple of Self and the number of bytes read from payload.
|
||||
fn load(
|
||||
/// In case of success, returns a tuple of Self and the remaining payload.
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError>;
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError>;
|
||||
|
||||
/// Load the specified bytes.
|
||||
///
|
||||
/// In case of success, returns a tuple of Self and the number of bytes read from the buffer.
|
||||
fn from_bytes(buf: &[u8]) -> Result<(Self, usize), TryFromPacketError> {
|
||||
/// In case of success, returns a tuple of Self and the remaining payload.
|
||||
fn from_bytes<'t>(
|
||||
buf: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
let (header, bytes_header) =
|
||||
Header::read_from(buf).ok_or(TryFromPacketError::TooSmall)?;
|
||||
let (result, bytes_payload) =
|
||||
Self::load(&header, &buf[bytes_header..])?;
|
||||
Ok((result, bytes_header + bytes_payload))
|
||||
let (result, remaining) = Self::load(&header, &buf[bytes_header..])?;
|
||||
Ok((result, remaining))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,13 +134,15 @@ macro_rules! derive_try_from_packet {
|
|||
|
||||
fn try_from(packet: Packet) -> Result<Self, Self::Error> {
|
||||
let payload = packet.payload.as_deref().unwrap_or(&[]);
|
||||
let (result, read_bytes) = Self::load(&packet.header, payload)?;
|
||||
//if payload.len() != read_bytes {
|
||||
// return Err(TryFromPacketError::UnexpectedPayloadSize {
|
||||
// actual: payload.len(),
|
||||
// expected: read_bytes,
|
||||
// });
|
||||
//}
|
||||
let (result, remaining) = Self::load(&packet.header, payload)?;
|
||||
let remaining_len = remaining.len();
|
||||
if remaining_len != 0 {
|
||||
let payload_len = payload.len();
|
||||
return Err(TryFromPacketError::UnexpectedPayloadSize {
|
||||
actual: payload_len,
|
||||
expected: payload_len - remaining_len,
|
||||
});
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use crate::{
|
||||
command_code::CommandCode, commands::errors::TryFromPacketError,
|
||||
BitVecCommand, BitmapCommand, BitmapLegacyCommand, BrightnessGridCommand,
|
||||
CharGridCommand, ClearCommand, Cp437GridCommand, FadeOutCommand,
|
||||
GlobalBrightnessCommand, HardResetCommand, Header, LoadableFromPacket,
|
||||
Packet, TryIntoPacketError,
|
||||
BitVecCommand, BitmapCommand, BrightnessGridCommand, CharGridCommand,
|
||||
ClearCommand, Cp437GridCommand, FadeOutCommand, GlobalBrightnessCommand,
|
||||
HardResetCommand, Header, LoadableFromPacket, Packet, TryIntoPacketError,
|
||||
};
|
||||
|
||||
/// This enum contains all commands provided by the library.
|
||||
|
|
@ -28,14 +27,14 @@ pub enum TypedCommand {
|
|||
}
|
||||
|
||||
impl LoadableFromPacket for TypedCommand {
|
||||
fn load(
|
||||
fn load<'t>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(Self, usize), TryFromPacketError> {
|
||||
fn load_as_typed<T: LoadableFromPacket + Into<TypedCommand>>(
|
||||
payload: &'t [u8],
|
||||
) -> Result<(Self, &'t [u8]), TryFromPacketError> {
|
||||
fn load_as_typed<'t, T: LoadableFromPacket + Into<TypedCommand>>(
|
||||
header: &Header,
|
||||
payload: &[u8],
|
||||
) -> Result<(TypedCommand, usize), TryFromPacketError> {
|
||||
payload: &'t [u8],
|
||||
) -> Result<(TypedCommand, &'t [u8]), TryFromPacketError> {
|
||||
let (cmd, read) = T::load(header, payload)?;
|
||||
Ok((cmd.into(), read))
|
||||
}
|
||||
|
|
@ -64,7 +63,7 @@ impl LoadableFromPacket for TypedCommand {
|
|||
}
|
||||
#[allow(deprecated)]
|
||||
CommandCode::BitmapLegacy => {
|
||||
load_as_typed::<BitmapLegacyCommand>(header, payload)
|
||||
load_as_typed::<crate::BitmapLegacyCommand>(header, payload)
|
||||
}
|
||||
CommandCode::BitmapLinear
|
||||
| CommandCode::BitmapLinearOr
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
};
|
||||
use log::error;
|
||||
use lzma::LzmaReader;
|
||||
use std::io::Read;
|
||||
use std::io::{IoSliceMut, Read};
|
||||
|
||||
pub struct Lzma;
|
||||
|
||||
|
|
@ -21,13 +21,61 @@ impl CompressionAlgo for Lzma {
|
|||
fn decompress(
|
||||
payload: &[u8],
|
||||
expected_size_hint: usize,
|
||||
) -> Result<(Vec<u8>, usize), CompressionError> {
|
||||
) -> Result<(Vec<u8>, &[u8]), CompressionError> {
|
||||
let mut counted = Counted::new(payload);
|
||||
let mut output: Vec<u8> = Vec::with_capacity(expected_size_hint);
|
||||
let mut reader = LzmaReader::new_decompressor(payload)
|
||||
|
||||
let mut reader = LzmaReader::new_decompressor(&mut counted)
|
||||
.map_err(|_| CompressionError::LibraryError)?;
|
||||
let read = reader
|
||||
reader
|
||||
.read_to_end(&mut output)
|
||||
.map_err(|_| CompressionError::CompressionFailed)?;
|
||||
Ok((output, read))
|
||||
|
||||
let (_, remaining) = payload.split_at(counted.total_read());
|
||||
Ok((output, remaining))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct Counted<R: Read> {
|
||||
inner: R,
|
||||
count: usize,
|
||||
}
|
||||
|
||||
impl<R: Read> Counted<R> {
|
||||
pub(crate) fn new(inner: R) -> Self {
|
||||
Self { inner, count: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Read> Counted<R> {
|
||||
pub(crate) fn total_read(&self) -> usize {
|
||||
self.count
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Read> Read for Counted<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
self.inner.read(buf).inspect(|count| self.count += *count)
|
||||
}
|
||||
|
||||
fn read_vectored(
|
||||
&mut self,
|
||||
bufs: &mut [IoSliceMut<'_>],
|
||||
) -> std::io::Result<usize> {
|
||||
self.inner
|
||||
.read_vectored(bufs)
|
||||
.inspect(|count| self.count += *count)
|
||||
}
|
||||
|
||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
|
||||
self.inner
|
||||
.read_to_end(buf)
|
||||
.inspect(|count| self.count += *count)
|
||||
}
|
||||
|
||||
fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
|
||||
self.inner
|
||||
.read_to_string(buf)
|
||||
.inspect(|count| self.count += *count)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,17 +26,17 @@ pub(crate) enum CompressionError {
|
|||
pub(crate) trait CompressionAlgo {
|
||||
const CODE: CompressionCode;
|
||||
fn compress(payload: &[u8]) -> Result<Vec<u8>, CompressionError>;
|
||||
fn decompress(
|
||||
payload: &[u8],
|
||||
fn decompress<'t>(
|
||||
payload: &'t [u8],
|
||||
expected_size_hint: usize,
|
||||
) -> Result<(Vec<u8>, usize), CompressionError>;
|
||||
) -> Result<(Vec<u8>, &'t [u8]), CompressionError>;
|
||||
}
|
||||
|
||||
pub(crate) fn decompress(
|
||||
pub(crate) fn decompress<'t>(
|
||||
kind: CompressionCode,
|
||||
#[allow(unused, reason = "depends on features")] payload: &[u8],
|
||||
#[allow(unused, reason = "depends on features")] payload: &'t [u8],
|
||||
expected_size_hint: usize,
|
||||
) -> Result<(Vec<u8>, usize), CompressionError> {
|
||||
) -> Result<(Vec<u8>, &'t [u8]), CompressionError> {
|
||||
match kind {
|
||||
CompressionCode::Uncompressed => {
|
||||
uncompressed::Uncompressed::decompress(payload, expected_size_hint)
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@ impl CompressionAlgo for Uncompressed {
|
|||
Ok(payload.to_vec())
|
||||
}
|
||||
|
||||
fn decompress(
|
||||
payload: &[u8],
|
||||
fn decompress<'t>(
|
||||
payload: &'t [u8],
|
||||
expected_size_hint: usize,
|
||||
) -> Result<(Vec<u8>, usize), CompressionError> {
|
||||
Ok((
|
||||
payload[..expected_size_hint.min(payload.len())].to_vec(),
|
||||
expected_size_hint,
|
||||
))
|
||||
) -> Result<(Vec<u8>, &'t [u8]), CompressionError> {
|
||||
let index = expected_size_hint.min(payload.len());
|
||||
let (payload, remaining) = payload.split_at(index);
|
||||
Ok((payload.to_vec(), remaining))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ pub(crate) struct Zstd;
|
|||
|
||||
impl CompressionAlgo for Zstd {
|
||||
const CODE: CompressionCode = CompressionCode::Zstd;
|
||||
|
||||
|
||||
fn compress(payload: &[u8]) -> Result<Payload, CompressionError> {
|
||||
let buf = Vec::with_capacity(payload.len());
|
||||
let mut encoder = Encoder::new(buf, DEFAULT_COMPRESSION_LEVEL)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue