keramics_core/
data_stream.rs

1/* Copyright 2024-2025 Joachim Metz <joachim.metz@gmail.com>
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may
5 * obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 * License for the specific language governing permissions and limitations
11 * under the License.
12 */
13
14use std::io::SeekFrom;
15use std::sync::{Arc, RwLock};
16
17use super::errors::ErrorTrace;
18
19pub type DataStreamReference = Arc<RwLock<dyn DataStream>>;
20
21/// Data stream trait.
22pub trait DataStream: Send + Sync {
23    /// Retrieves the size of the data.
24    fn get_size(&mut self) -> Result<u64, ErrorTrace>;
25
26    /// Reads data at the current position.
27    fn read(&mut self, buf: &mut [u8]) -> Result<usize, ErrorTrace>;
28
29    /// Reads data at a specific position.
30    #[inline(always)]
31    fn read_at_position(&mut self, buf: &mut [u8], pos: SeekFrom) -> Result<usize, ErrorTrace> {
32        self.seek(pos)?;
33        self.read(buf)
34    }
35
36    /// Reads an exact amount of data at the current position.
37    #[inline(always)]
38    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), ErrorTrace> {
39        let read_size: usize = buf.len();
40        let read_count: usize = self.read(buf)?;
41
42        if read_count != read_size {
43            return Err(crate::error_trace_new!("Unable to read the exact amount"));
44        }
45        Ok(())
46    }
47
48    /// Reads an exact amount of data at a specific position.
49    #[inline(always)]
50    fn read_exact_at_position(&mut self, buf: &mut [u8], pos: SeekFrom) -> Result<u64, ErrorTrace> {
51        let offset: u64 = self.seek(pos)?;
52        let read_size: usize = buf.len();
53        let read_count: usize = self.read(buf)?;
54
55        if read_count != read_size {
56            return Err(crate::error_trace_new!("Unable to read the exact amount"));
57        }
58        Ok(offset)
59    }
60
61    /// Sets the current position of the data.
62    fn seek(&mut self, pos: SeekFrom) -> Result<u64, ErrorTrace>;
63}