mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
Import the std modules used in the disk-format handlers instead of spelling the full paths at every use site. Signed-off-by: Henry Hrvoje Tonkovac <htonkovac@gmail.com> Assisted-by: Claude:Opus-4.8
90 lines
2.6 KiB
Rust
90 lines
2.6 KiB
Rust
// Copyright 2025 The Cloud Hypervisor Authors. All rights reserved.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use std::{io, result};
|
|
|
|
use thiserror::Error;
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum Error {
|
|
#[error("Zlib decompress error")]
|
|
ZlibDecompress(#[source] flate2::DecompressError),
|
|
#[error("Zlib unexpected status: {0:?}")]
|
|
ZlibUnexpectedStatus(flate2::Status),
|
|
#[error("Zstd decompress error")]
|
|
ZstdDecompress(#[source] io::Error),
|
|
#[error("Zstd: failed to fill buffer")]
|
|
ZstdFillBuffer(#[source] io::Error),
|
|
}
|
|
|
|
pub type Result<T> = result::Result<T, Error>;
|
|
|
|
/// Generic trait for decoding zlib/zstd formats
|
|
pub trait Decoder: Send + Sync {
|
|
fn decode(&self, input: &[u8], output: &mut [u8]) -> Result<usize>;
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct ZlibDecoder {}
|
|
|
|
impl Decoder for ZlibDecoder {
|
|
fn decode(&self, input: &[u8], output: &mut [u8]) -> Result<usize> {
|
|
use flate2::{Decompress, FlushDecompress, Status};
|
|
|
|
let mut decompressor = Decompress::new(false);
|
|
let status = decompressor
|
|
.decompress(input, output, FlushDecompress::Finish)
|
|
.map_err(Error::ZlibDecompress)?;
|
|
if status == Status::StreamEnd {
|
|
Ok(decompressor.total_out() as usize)
|
|
} else {
|
|
Err(Error::ZlibUnexpectedStatus(status))
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct ZstdDecoder {}
|
|
|
|
impl Decoder for ZstdDecoder {
|
|
fn decode(&self, input: &[u8], output: &mut [u8]) -> Result<usize> {
|
|
use std::io::Read;
|
|
|
|
let mut decoder = zstd::stream::read::Decoder::new(input).map_err(Error::ZstdDecompress)?;
|
|
let decoded_size = decoder.read(output).map_err(Error::ZstdFillBuffer)?;
|
|
Ok(decoded_size)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_zlib_decode() {
|
|
let d = ZlibDecoder::default();
|
|
let valid_input = vec![99, 96, 100, 98, 6, 0];
|
|
let mut output1 = vec![0; 4];
|
|
d.decode(&valid_input, &mut output1).unwrap();
|
|
assert_eq!(&output1, b"\x00\x01\x02\x03");
|
|
|
|
let invalid_input = vec![1, 2, 3, 4];
|
|
let mut output2 = vec![0; 1024];
|
|
d.decode(&invalid_input, &mut output2).unwrap_err();
|
|
}
|
|
|
|
#[test]
|
|
fn test_zstd_decode() {
|
|
let d = ZstdDecoder::default();
|
|
let valid_input = vec![40, 181, 47, 253, 32, 2, 17, 0, 0, 1, 254];
|
|
let mut output1 = vec![0; 2];
|
|
d.decode(&valid_input, &mut output1).unwrap();
|
|
assert_eq!(&output1, b"\x01\xfe");
|
|
|
|
let invalid_input = vec![1, 2, 3, 4];
|
|
let mut output2 = vec![0; 1024];
|
|
d.decode(&invalid_input, &mut output2).unwrap_err();
|
|
}
|
|
}
|