Skip to main content

dsi_bitstream/impls/
mem_word_writer.rs

1/*
2 * SPDX-FileCopyrightText: 2023 Tommaso Fontana
3 * SPDX-FileCopyrightText: 2023 Inria
4 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
5 *
6 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
7 */
8
9#[cfg(feature = "alloc")]
10use alloc::vec::Vec;
11#[cfg(feature = "alloc")]
12use core::convert::Infallible;
13#[cfg(feature = "mem_dbg")]
14use mem_dbg::{MemDbg, MemSize};
15
16use crate::traits::*;
17
18/// An implementation of [`WordRead`], [`WordWrite`], and [`WordSeek`] for a
19/// mutable slice.
20///
21/// Writing beyond the end of the slice will return an error.
22///
23/// # Examples
24/// ```
25/// # fn main() -> Result<(), Box<dyn core::error::Error>> {
26/// use dsi_bitstream::prelude::*;
27///
28/// let mut words: [u64; 2] = [
29///     0x0043b59fcdf16077,
30///     0x702863e6f9739b86,
31/// ];
32///
33/// let mut word_writer = MemWordWriterSlice::new(&mut words);
34///
35/// // the stream is read sequentially
36/// assert_eq!(word_writer.word_pos()?, 0);
37/// assert_eq!(word_writer.read_word()?, 0x0043b59fcdf16077);
38/// assert_eq!(word_writer.word_pos()?, 1);
39/// assert_eq!(word_writer.read_word()?, 0x702863e6f9739b86);
40/// assert_eq!(word_writer.word_pos()?, 2);
41/// assert!(word_writer.read_word().is_err());
42///
43/// // you can change position
44/// assert!(word_writer.set_word_pos(1).is_ok());
45/// assert_eq!(word_writer.word_pos()?, 1);
46/// assert_eq!(word_writer.read_word()?, 0x702863e6f9739b86);
47///
48/// // errored set position doesn't change the current position
49/// assert_eq!(word_writer.word_pos()?, 2);
50/// assert!(word_writer.set_word_pos(100).is_err());
51/// assert_eq!(word_writer.word_pos()?, 2);
52///
53/// // we can write and read back!
54/// assert!(word_writer.set_word_pos(0).is_ok());
55/// assert!(word_writer.write_word(0x0b801b2bf696e8d2).is_ok());
56/// assert_eq!(word_writer.word_pos()?, 1);
57/// assert!(word_writer.set_word_pos(0).is_ok());
58/// assert_eq!(word_writer.read_word()?, 0x0b801b2bf696e8d2);
59/// assert_eq!(word_writer.word_pos()?, 1);
60/// # Ok(())
61/// # }
62/// ```
63#[derive(Debug, PartialEq)]
64#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
65pub struct MemWordWriterSlice<W: Word, B> {
66    data: B,
67    word_index: usize,
68    _marker: core::marker::PhantomData<W>,
69}
70
71impl<W: Word, B: AsRef<[W]>> MemWordWriterSlice<W, B> {
72    /// Creates a new [`MemWordWriterSlice`] from a slice.
73    #[must_use]
74    pub const fn new(data: B) -> Self {
75        Self {
76            data,
77            word_index: 0,
78            _marker: core::marker::PhantomData,
79        }
80    }
81
82    /// Returns the number of words in the underlying slice.
83    #[must_use]
84    pub fn len(&self) -> usize {
85        self.data.as_ref().len()
86    }
87
88    /// Returns `true` if the underlying slice is empty.
89    #[must_use]
90    pub fn is_empty(&self) -> bool {
91        self.len() == 0
92    }
93
94    /// Consumes this writer and returns the underlying data.
95    #[must_use]
96    pub fn into_inner(self) -> B {
97        self.data
98    }
99}
100
101/// An implementation of [`WordRead`], [`WordWrite`], and [`WordSeek`]
102/// for a mutable vector.
103///
104/// The vector will be extended as new data is written.
105///
106/// # Examples
107/// ```
108/// # fn main() -> Result<(), Box<dyn core::error::Error>> {
109/// use dsi_bitstream::prelude::*;
110///
111/// let mut words: Vec<u64> = vec![
112///     0x0043b59fcdf16077,
113/// ];
114///
115/// let mut word_writer = MemWordWriterVec::new(&mut words);
116///
117/// // the stream is read sequentially
118/// assert_eq!(word_writer.word_pos()?, 0);
119/// assert!(word_writer.write_word(0).is_ok());
120/// assert_eq!(word_writer.word_pos()?, 1);
121/// assert!(word_writer.write_word(1).is_ok());
122/// assert_eq!(word_writer.word_pos()?, 2);
123/// # Ok(())
124/// # }
125/// ```
126#[derive(Debug, Default, PartialEq)]
127#[cfg_attr(feature = "mem_dbg", derive(MemDbg, MemSize))]
128#[cfg(feature = "alloc")]
129pub struct MemWordWriterVec<W: Word, B> {
130    data: B,
131    word_index: usize,
132    _marker: core::marker::PhantomData<W>,
133}
134
135#[cfg(feature = "alloc")]
136impl<W: Word, B: AsRef<Vec<W>>> MemWordWriterVec<W, B> {
137    /// Creates a new [`MemWordWriterVec`] from a vector.
138    #[must_use]
139    pub const fn new(data: B) -> Self {
140        Self {
141            data,
142            word_index: 0,
143            _marker: core::marker::PhantomData,
144        }
145    }
146
147    /// Returns the number of words in the underlying vector.
148    #[must_use]
149    pub fn len(&self) -> usize {
150        self.data.as_ref().len()
151    }
152
153    /// Returns `true` if the underlying vector is empty.
154    #[must_use]
155    pub fn is_empty(&self) -> bool {
156        self.len() == 0
157    }
158
159    /// Consumes this writer and returns the underlying data.
160    #[must_use]
161    pub fn into_inner(self) -> B {
162        self.data
163    }
164}
165
166impl<W: Word, B: AsRef<[W]>> WordRead for MemWordWriterSlice<W, B> {
167    type Error = WordError;
168    type Word = W;
169
170    #[inline]
171    fn read_word(&mut self) -> Result<W, WordError> {
172        match self.data.as_ref().get(self.word_index) {
173            Some(word) => {
174                self.word_index += 1;
175                Ok(*word)
176            }
177            None => Err(WordError::UnexpectedEof {
178                word_pos: self.word_index,
179            }),
180        }
181    }
182}
183
184impl<W: Word, B: AsRef<[W]>> WordSeek for MemWordWriterSlice<W, B> {
185    type Error = WordError;
186
187    #[inline(always)]
188    fn word_pos(&mut self) -> Result<u64, WordError> {
189        Ok(self.word_index as u64)
190    }
191
192    #[inline(always)]
193    fn set_word_pos(&mut self, word_index: u64) -> Result<(), WordError> {
194        if word_index > self.data.as_ref().len() as u64 {
195            Err(WordError::UnexpectedEof {
196                word_pos: self.word_index,
197            })
198        } else {
199            self.word_index = word_index as usize;
200            Ok(())
201        }
202    }
203}
204
205impl<W: Word, B: AsMut<[W]>> WordWrite for MemWordWriterSlice<W, B> {
206    type Error = WordError;
207    type Word = W;
208
209    #[inline]
210    fn write_word(&mut self, word: W) -> Result<(), WordError> {
211        match self.data.as_mut().get_mut(self.word_index) {
212            Some(word_ref) => {
213                self.word_index += 1;
214                *word_ref = word;
215                Ok(())
216            }
217            None => Err(WordError::UnexpectedEof {
218                word_pos: self.word_index,
219            }),
220        }
221    }
222
223    fn flush(&mut self) -> Result<(), Self::Error> {
224        Ok(())
225    }
226}
227
228#[cfg(feature = "alloc")]
229impl<W: Word, B: AsMut<Vec<W>>> WordWrite for MemWordWriterVec<W, B> {
230    type Error = Infallible;
231    type Word = W;
232
233    #[inline]
234    fn write_word(&mut self, word: W) -> Result<(), Infallible> {
235        let data = self.data.as_mut();
236        if self.word_index >= data.len() {
237            data.resize(self.word_index + 1, W::ZERO);
238        }
239        data[self.word_index] = word;
240        self.word_index += 1;
241        Ok(())
242    }
243
244    fn flush(&mut self) -> Result<(), Self::Error> {
245        Ok(())
246    }
247}
248
249#[cfg(feature = "alloc")]
250impl<W: Word, B: AsRef<Vec<W>>> WordRead for MemWordWriterVec<W, B> {
251    type Error = WordError;
252    type Word = W;
253
254    #[inline]
255    fn read_word(&mut self) -> Result<W, WordError> {
256        match self.data.as_ref().get(self.word_index) {
257            Some(word) => {
258                self.word_index += 1;
259                Ok(*word)
260            }
261            None => Err(WordError::UnexpectedEof {
262                word_pos: self.word_index,
263            }),
264        }
265    }
266}
267
268#[cfg(feature = "alloc")]
269impl<W: Word, B: AsRef<Vec<W>>> WordSeek for MemWordWriterVec<W, B> {
270    type Error = WordError;
271
272    #[inline(always)]
273    fn word_pos(&mut self) -> Result<u64, WordError> {
274        Ok(self.word_index as u64)
275    }
276
277    #[inline(always)]
278    fn set_word_pos(&mut self, word_index: u64) -> Result<(), WordError> {
279        if word_index > self.data.as_ref().len() as u64 {
280            Err(WordError::UnexpectedEof {
281                word_pos: self.word_index,
282            })
283        } else {
284            self.word_index = word_index as usize;
285            Ok(())
286        }
287    }
288}