Skip to main content

ozlrip_core/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr(feature = "paranoid", forbid(unsafe_code))]
3
4extern crate alloc;
5
6use alloc::string::String;
7use alloc::vec::Vec;
8use core::fmt;
9
10pub type Result<T> = core::result::Result<T, Error>;
11
12#[derive(Clone, Debug, Eq, PartialEq)]
13pub struct Error {
14    kind: ErrorKind,
15    offset: Option<usize>,
16    detail: Option<String>,
17}
18
19impl Error {
20    pub const fn new(kind: ErrorKind) -> Self {
21        Self {
22            kind,
23            offset: None,
24            detail: None,
25        }
26    }
27
28    pub const fn at(kind: ErrorKind, offset: usize) -> Self {
29        Self {
30            kind,
31            offset: Some(offset),
32            detail: None,
33        }
34    }
35
36    #[must_use]
37    pub fn with_detail(mut self, detail: impl Into<String>) -> Self {
38        self.detail = Some(detail.into());
39        self
40    }
41
42    pub const fn kind(&self) -> ErrorKind {
43        self.kind
44    }
45
46    pub const fn offset(&self) -> Option<usize> {
47        self.offset
48    }
49
50    pub fn detail(&self) -> Option<&str> {
51        self.detail.as_deref()
52    }
53}
54
55impl fmt::Display for Error {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        write!(f, "{:?}", self.kind)?;
58        if let Some(offset) = self.offset {
59            write!(f, " at byte {offset}")?;
60        }
61        if let Some(detail) = &self.detail {
62            write!(f, ": {detail}")?;
63        }
64        Ok(())
65    }
66}
67
68#[cfg(feature = "std")]
69impl std::error::Error for Error {}
70
71#[derive(Clone, Copy, Debug, Eq, PartialEq)]
72pub enum ErrorKind {
73    Truncated,
74    Malformed,
75    Unsupported,
76    LimitExceeded,
77    ChecksumMismatch,
78    InvalidGraph,
79    InvalidType,
80    IntegerOverflow,
81}
82
83#[derive(Clone, Copy, Debug, Eq, PartialEq)]
84pub struct Limits {
85    pub max_frame_bytes: usize,
86    pub max_decoded_bytes: usize,
87    pub max_chunks: usize,
88    pub max_nodes: usize,
89    pub max_streams: usize,
90    pub max_transform_header_bytes: usize,
91    pub max_stored_stream_bytes: usize,
92    pub max_buffer_bytes: usize,
93    pub max_graph_depth: usize,
94    pub max_expansion_ratio: usize,
95}
96
97impl Limits {
98    pub const fn strict() -> Self {
99        Self {
100            max_frame_bytes: 64 * 1024 * 1024,
101            max_decoded_bytes: 64 * 1024 * 1024,
102            max_chunks: 16_384,
103            max_nodes: 65_536,
104            max_streams: 131_072,
105            max_transform_header_bytes: 16 * 1024 * 1024,
106            max_stored_stream_bytes: 64 * 1024 * 1024,
107            max_buffer_bytes: 64 * 1024 * 1024,
108            max_graph_depth: 1024,
109            max_expansion_ratio: 256,
110        }
111    }
112
113    pub const fn paranoid() -> Self {
114        Self {
115            max_frame_bytes: 16 * 1024 * 1024,
116            max_decoded_bytes: 16 * 1024 * 1024,
117            max_chunks: 4096,
118            max_nodes: 16_384,
119            max_streams: 32_768,
120            max_transform_header_bytes: 4 * 1024 * 1024,
121            max_stored_stream_bytes: 16 * 1024 * 1024,
122            max_buffer_bytes: 16 * 1024 * 1024,
123            max_graph_depth: 256,
124            max_expansion_ratio: 64,
125        }
126    }
127}
128
129impl Default for Limits {
130    fn default() -> Self {
131        if cfg!(feature = "paranoid") {
132            Self::paranoid()
133        } else {
134            Self::strict()
135        }
136    }
137}
138
139#[derive(Clone, Debug, Eq, PartialEq)]
140pub struct FrameInfo {
141    pub format_version: u32,
142    pub frame_bytes: usize,
143    pub header_bytes: usize,
144    pub decoded_bytes: Option<usize>,
145    pub chunks: usize,
146    pub inputs: usize,
147    pub output_types: Vec<FrameValueType>,
148    pub output_sizes: Vec<Option<u64>>,
149    pub output_elements: Vec<Option<u64>>,
150    pub transforms: usize,
151    pub stored_streams: usize,
152    pub regenerated_streams: usize,
153    pub has_decoded_checksum: bool,
154    pub has_encoded_checksum: bool,
155    pub has_comment: bool,
156    pub comment: Option<Vec<u8>>,
157    pub dictionary_bundle_id: Option<Vec<u8>>,
158}
159
160#[derive(Clone, Copy, Debug, Eq, PartialEq)]
161pub enum FrameValueType {
162    Serial,
163    Struct,
164    Numeric,
165    String,
166}