bitwarden_crypto/stream/
large_memory_buffer.rs1pub struct Buffer {
11 #[cfg(target_arch = "wasm32")]
23 inner: js_sys::Uint8Array,
24
25 #[cfg(not(target_arch = "wasm32"))]
28 inner: Vec<u8>,
29
30 capacity: usize,
32
33 position: usize,
35}
36
37#[derive(Debug)]
38pub(crate) struct InvalidIndexError;
39
40impl Buffer {
41 pub fn new(capacity: usize) -> Self {
42 Self {
43 #[cfg(target_arch = "wasm32")]
44 inner: js_sys::Uint8Array::new_with_length(capacity as u32).into(),
45
46 #[cfg(not(target_arch = "wasm32"))]
47 inner: vec![0; capacity],
48
49 capacity,
50 position: 0,
51 }
52 }
53
54 pub fn index(&self, index: std::ops::Range<usize>) -> Result<Vec<u8>, InvalidIndexError> {
55 if index.end > self.capacity || index.start > index.end {
56 return Err(InvalidIndexError);
57 }
58
59 #[cfg(target_arch = "wasm32")]
60 {
61 Ok(self
62 .inner
63 .slice(index.start as u32, index.end as u32)
64 .to_vec())
65 }
66
67 #[cfg(not(target_arch = "wasm32"))]
68 {
69 Ok(self.inner[index].to_vec())
70 }
71 }
72
73 pub fn append(&mut self, data: &[u8]) -> Result<(), InvalidIndexError> {
74 if self.position + data.len() > self.capacity {
75 return Err(InvalidIndexError);
76 }
77
78 #[cfg(target_arch = "wasm32")]
79 {
80 self.inner
81 .subarray(self.position as u32, (self.position + data.len()) as u32)
82 .copy_from(data);
83 }
84
85 #[cfg(not(target_arch = "wasm32"))]
86 {
87 self.inner[self.position..self.position + data.len()].copy_from_slice(data);
88 }
89
90 self.position += data.len();
91 Ok(())
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_buffer() {
101 let mut buffer = Buffer::new(5);
102 buffer
103 .append(&[1, 2, 3, 4, 5])
104 .expect("range must be valid");
105 assert_eq!(&buffer.index(0..5).unwrap(), &[1, 2, 3, 4, 5]);
106 }
107
108 #[test]
109 fn test_append_advances_write_cursor() {
110 let mut buffer = Buffer::new(9);
111 buffer
112 .append(&[1, 2, 3, 4, 5])
113 .expect("range must be valid");
114 buffer.append(&[6, 7, 8, 9]).expect("range must be valid");
115 assert_eq!(&buffer.index(0..9).unwrap(), &[1, 2, 3, 4, 5, 6, 7, 8, 9]);
116 }
117
118 #[test]
119 fn test_append_past_capacity_errors() {
120 let mut buffer = Buffer::new(4);
121 assert!(buffer.append(&[1, 2, 3, 4, 5]).is_err());
122 }
123}