sos_core/
file_identity.rs

1//! Helper functions to read and write the magic identity
2//! bytes for file formats.
3use crate::{Error, Result};
4use binary_stream::futures::BinaryReader;
5use tokio::io::{AsyncReadExt, AsyncSeek};
6
7/// String of formatted identity bytes for error messages.
8#[doc(hidden)]
9pub fn format_identity_bytes(identity: &[u8]) -> String {
10    let c =
11        std::str::from_utf8(identity).expect("identity bytes to be UTF-8");
12    format!("{:#04x?} ({})", identity, c)
13    /*
14    let c =
15        std::str::from_utf8(identity).expect("identity bytes to be UTF-8");
16    let mut s = String::new();
17    for (index, byte) in identity.iter().enumerate() {
18        s.push_str(&format!("{:#04x}", byte));
19        if index < identity.len() - 1 {
20            s.push_str(", ");
21        }
22    }
23    s.push_str(&format!(" ({})", c));
24    s
25    */
26}
27
28/// Read identity bytes.
29pub struct FileIdentity;
30
31impl FileIdentity {
32    /// Read the identity magic bytes from a slice.
33    pub fn read_slice(buffer: &[u8], identity: &[u8]) -> Result<()> {
34        if buffer.len() >= identity.len() {
35            for (index, ident) in identity.iter().enumerate() {
36                let byte = buffer[index];
37                if byte != *ident {
38                    return Err(Error::BadIdentity(
39                        byte,
40                        index,
41                        format_identity_bytes(identity),
42                    ));
43                }
44            }
45        } else {
46            return Err(Error::IdentityLength);
47        }
48        Ok(())
49    }
50
51    /// Read the identity magic bytes.
52    pub async fn read_identity<R: AsyncReadExt + AsyncSeek + Unpin + Send>(
53        reader: &mut BinaryReader<R>,
54        identity: &[u8],
55    ) -> Result<()> {
56        for (index, ident) in identity.iter().enumerate() {
57            let byte = reader.read_u8().await?;
58            if byte != *ident {
59                return Err(Error::BadIdentity(
60                    byte,
61                    index,
62                    format_identity_bytes(identity),
63                ));
64            }
65        }
66        Ok(())
67    }
68}