alpm_mtree/
utils.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//! File handling integration.

use std::io::Read;

use flate2::read::GzDecoder;

use crate::Error;

/// Two magic bytes that occur at the beginning of gzip files and can be used to detect whether a
/// file is gzip compressed.
/// Spec: <https://datatracker.ietf.org/doc/html/rfc1952#page-6>
pub const GZIP_MAGIC_NUMBER: [u8; 2] = [0x1f, 0x8b];

/// Creates a [`String`] from a byte vector which may be gzip compressed.
///
/// If `buffer` contains gzip compressed data, it decompressed before converting it into a
/// `String`.
/// Detects whether `buffer` contains gzip compressed data by checking if it is longer than two
/// bytes and whether the first two bytes are the [`GZIP_MAGIC_NUMBER`].
///
/// # Errors
///
/// Returns an error if
/// - `buffer` contains invalid gzip compressed data
/// - or `buffer` can not be converted to `String`.
pub fn mtree_buffer_to_string(buffer: Vec<u8>) -> Result<String, Error> {
    if buffer.len() >= 2 && [buffer[0], buffer[1]] == GZIP_MAGIC_NUMBER {
        let mut decoder = GzDecoder::new(buffer.as_slice());

        let mut content = String::new();
        decoder
            .read_to_string(&mut content)
            .map_err(Error::InvalidGzip)?;
        Ok(content)
    } else {
        Ok(String::from_utf8(buffer)?)
    }
}