cyfs_chunk_lib/
mem_chunk.rs1use std::io::{SeekFrom};
2use std::ops::{Deref, DerefMut};
3use cyfs_base::{BuckyError, BuckyErrorCode, BuckyResult};
4use crate::{Chunk, ChunkMeta, ChunkMut};
5
6pub struct MemChunk {
7 buf: Vec<u8>,
8 pos: usize,
9 data_len: usize,
10}
11
12impl MemChunk {
13 pub fn new(capacity: usize, data_len: usize) -> Self {
14 let mut buf = Vec::new();
15 buf.resize(capacity, 0);
16 Self {
17 buf,
18 pos: 0,
19 data_len
20 }
21 }
22
23 pub fn resize(&mut self, len: usize) {
24 if len < self.data_len {
25 self.data_len = len;
26 }
27 self.buf.resize(len, 0);
28 }
29
30 fn read_inner(&mut self, buf: &mut [u8]) -> BuckyResult<usize> {
31 if self.pos >= self.data_len {
32 Ok(0)
33 } else if buf.len() > self.data_len - self.pos {
34 unsafe {std::ptr::copy::<u8>(self.buf[self.pos..].as_ptr(), buf.as_mut_ptr(), self.data_len - self.pos)};
35 let read_len = self.data_len - self.pos;
36 self.pos = self.data_len;
37 Ok(read_len)
38 } else {
39 unsafe {std::ptr::copy::<u8>(self.buf[self.pos..self.pos + buf.len()].as_ptr(), buf.as_mut_ptr(), buf.len())};
40 let read_len = buf.len();
41 self.pos = self.pos + read_len;
42 Ok(read_len)
43 }
44 }
45
46 fn seek_inner(&mut self, pos: SeekFrom) -> BuckyResult<u64> {
47 match pos {
48 SeekFrom::Start(pos) => {
49 self.pos = pos as usize;
50 Ok(pos)
51 },
52 SeekFrom::End(pos) => {
53 if self.data_len as i64 + pos < 0 {
54 return Err(BuckyError::new(BuckyErrorCode::Failed, format!("seek failed")));
55 }
56 self.pos = (self.data_len as i64 + pos) as usize;
57 Ok(self.pos as u64)
58 },
59 SeekFrom::Current(pos) => {
60 if self.pos as i64 + pos < 0 {
61 return Err(BuckyError::new(BuckyErrorCode::Failed, format!("seek failed")));
62 }
63 self.pos = (self.pos as i64 + pos) as usize;
64 Ok(self.pos as u64)
65 }
66 }
67 }
68
69 fn write_inner(&mut self, buf: &[u8]) -> BuckyResult<usize> {
70 unsafe {
71 if self.pos + buf.len() >= self.buf.len() {
72 let write_size = self.buf.len() - self.pos;
73 std::ptr::copy(buf.as_ptr(), self.buf.as_mut_ptr(), write_size);
74 self.pos = self.buf.len();
75 if self.pos > self.data_len {
76 self.data_len = self.pos;
77 }
78 Ok(write_size)
79 } else {
80 std::ptr::copy(buf.as_ptr(), self.buf.as_mut_ptr(), buf.len());
81 self.pos += buf.len();
82 if self.pos > self.data_len {
83 self.data_len = self.pos;
84 }
85 Ok(buf.len())
86 }
87 }
88 }
89}
90
91impl From<Vec<u8>> for MemChunk {
92 fn from(buf: Vec<u8>) -> Self {
93 Self {
94 data_len: buf.len(),
95 buf,
96 pos: 0
97 }
98 }
99}
100
101impl Deref for MemChunk {
102 type Target = [u8];
103
104 fn deref(&self) -> &Self::Target {
105 self.buf.as_slice()
106 }
107}
108
109#[async_trait::async_trait]
110impl Chunk for MemChunk {
111 fn get_chunk_meta(&self) -> ChunkMeta {
112 ChunkMeta::MemChunk(self.buf[..self.data_len].to_vec())
113 }
114
115 fn get_len(&self) -> usize {
116 self.data_len
117 }
118
119 fn into_vec(self: Box<Self>) -> Vec<u8> {
120 if self.buf.len() == self.data_len {
121 self.buf
122 } else {
123 self.buf[..self.data_len].to_vec()
124 }
125 }
126
127 async fn read(&mut self, buf: &mut [u8]) -> BuckyResult<usize> {
128 self.read_inner(buf)
129 }
130
131 async fn seek(&mut self, pos: SeekFrom) -> BuckyResult<u64> {
132 self.seek_inner(pos)
133 }
134}
135
136impl DerefMut for MemChunk {
137 fn deref_mut(&mut self) -> &mut Self::Target {
138 self.buf.as_mut_slice()
139 }
140}
141
142#[async_trait::async_trait]
143impl ChunkMut for MemChunk {
144 async fn reset(&mut self) -> BuckyResult<()> {
145 self.pos = 0;
146 self.data_len = 0;
147 Ok(())
148 }
149
150 async fn write(&mut self, buf: &[u8]) -> BuckyResult<usize> {
151 self.write_inner(buf)
152 }
153
154 async fn flush(&mut self) -> BuckyResult<()> {
155 Ok(())
156 }
157}
158
159pub struct MemRefChunk<'a> {
160 buf: &'a [u8],
161 pos: usize,
162}
163
164impl<'a> MemRefChunk<'a> {
165 fn read_inner(&mut self, buf: &mut [u8]) -> BuckyResult<usize> {
166 if self.pos >= self.buf.len() {
167 Ok(0)
168 } else if buf.len() > self.buf.len() - self.pos {
169 unsafe {std::ptr::copy::<u8>(self.buf[self.pos..].as_ptr(), buf.as_mut_ptr(), self.buf.len() - self.pos)};
170 let read_len = self.buf.len() - self.pos;
171 self.pos = self.buf.len();
172 Ok(read_len)
173 } else {
174 unsafe {std::ptr::copy::<u8>(self.buf[self.pos..self.pos + buf.len()].as_ptr(), buf.as_mut_ptr(), buf.len())};
175 let read_len = buf.len();
176 self.pos = self.pos + read_len;
177 Ok(read_len)
178 }
179 }
180
181 fn seek_inner(&mut self, pos: SeekFrom) -> BuckyResult<u64> {
182 match pos {
183 SeekFrom::Start(pos) => {
184 self.pos = pos as usize;
185 Ok(pos)
186 },
187 SeekFrom::End(pos) => {
188 if self.buf.len() as i64 + pos < 0 {
189 return Err(BuckyError::new(BuckyErrorCode::Failed, format!("seek failed")));
190 }
191 self.pos = (self.buf.len() as i64 + pos) as usize;
192 Ok(self.pos as u64)
193 },
194 SeekFrom::Current(pos) => {
195 if self.pos as i64 + pos < 0 {
196 return Err(BuckyError::new(BuckyErrorCode::Failed, format!("seek failed")));
197 }
198 self.pos = (self.pos as i64 + pos) as usize;
199 Ok(self.pos as u64)
200 }
201 }
202 }
203}
204impl <'a> From<&'a [u8]> for MemRefChunk<'a> {
205 fn from(buf: &'a [u8]) -> Self {
206 Self {
207 buf,
208 pos: 0
209 }
210 }
211}
212
213impl <'a> Deref for MemRefChunk<'a> {
214 type Target = [u8];
215
216 fn deref(&self) -> &'a Self::Target {
217 self.buf
218 }
219}
220
221#[async_trait::async_trait]
222impl <'a> Chunk for MemRefChunk<'a> {
223 fn get_chunk_meta(&self) -> ChunkMeta {
224 ChunkMeta::MemChunk(self.buf.to_vec())
225 }
226
227 fn get_len(&self) -> usize {
228 self.buf.len()
229 }
230
231 fn into_vec(self: Box<Self>) -> Vec<u8> {
232 self.buf.to_vec()
233 }
234
235 async fn read(&mut self, buf: &mut [u8]) -> BuckyResult<usize> {
236 self.read_inner(buf)
237 }
238
239 async fn seek(&mut self, pos: SeekFrom) -> BuckyResult<u64> {
240 self.seek_inner(pos)
241 }
242}
243
244#[cfg(test)]
245mod test_mem_chunk {
246 use std::sync::Arc;
247 use crate::{Chunk, ChunkMut, MemChunk, MemRefChunk, SharedMemChunk};
248
249 #[test]
250 fn test_mem_ref_chunk() {
251 let buf = {
252 let mut buf = Vec::<u8>::new();
253 buf.resize(20, 0);
254 Arc::new(buf)
255 };
256 let chunk = MemRefChunk::from(buf.as_slice());
257
258 let s = &chunk[..];
259 assert_eq!(s.len(), 20);
260 }
261
262 #[test]
263 fn test_mem_async_test() {
264 async_std::task::block_on(async move {
265 let mut mem_chunk = MemChunk::new(20, 0);
266 mem_chunk.write("test".as_bytes()).await.unwrap();
267 })
268 }
269
270 #[test]
271 fn test_share_mem_test() {
272 async_std::task::block_on(async move {
273 let mut mem_chunk = SharedMemChunk::new(20, 0, "test").unwrap();
274 mem_chunk.write("test".as_bytes()).await.unwrap();
275
276 let mut mem_chunk2 = SharedMemChunk::new(20, mem_chunk.get_len(), "test").unwrap();
277 let mut buf = [0u8;4];
278 mem_chunk2.read(&mut buf).await.unwrap();
279 println!("{} {}", mem_chunk.len(), mem_chunk2.len());
280
281 assert_eq!(20, mem_chunk.len());
282 assert_eq!(20, mem_chunk2.len());
283 assert_eq!("test", String::from_utf8_lossy(&buf).to_string().as_str());
284 })
285 }
286}