alpm_mtree/utils.rs
1//! File handling integration.
2
3use std::io::Read;
4
5use flate2::read::GzDecoder;
6
7use crate::Error;
8
9/// Two magic bytes that occur at the beginning of gzip files and can be used to detect whether a
10/// file is gzip compressed.
11/// Spec: <https://datatracker.ietf.org/doc/html/rfc1952#page-6>
12pub const GZIP_MAGIC_NUMBER: [u8; 2] = [0x1f, 0x8b];
13
14/// Creates a [`String`] from a byte vector which may be gzip compressed.
15///
16/// If `buffer` contains gzip compressed data, it decompressed before converting it into a
17/// `String`.
18/// Detects whether `buffer` contains gzip compressed data by checking if it is longer than two
19/// bytes and whether the first two bytes are the [`GZIP_MAGIC_NUMBER`].
20///
21/// # Errors
22///
23/// Returns an error if
24/// - `buffer` contains invalid gzip compressed data
25/// - or `buffer` can not be converted to `String`.
26pub fn mtree_buffer_to_string(buffer: Vec<u8>) -> Result<String, Error> {
27 if buffer.len() >= 2 && [buffer[0], buffer[1]] == GZIP_MAGIC_NUMBER {
28 let mut decoder = GzDecoder::new(buffer.as_slice());
29
30 let mut content = String::new();
31 decoder
32 .read_to_string(&mut content)
33 .map_err(Error::InvalidGzip)?;
34 Ok(content)
35 } else {
36 Ok(String::from_utf8(buffer)?)
37 }
38}