1use std::ops::{Bound, Range, RangeBounds};
2
3use bytes::{Buf, Bytes};
4use exocore_core::framing::FrameReader;
5
6pub trait Data: FrameReader<OwnedType = Bytes> + Clone {
9 fn slice<R: RangeBounds<usize>>(&self, r: R) -> &[u8];
10
11 fn view<R: RangeBounds<usize>>(&self, r: R) -> Self;
12
13 fn len(&self) -> usize;
14
15 fn is_empty(&self) -> bool {
16 self.len() == 0
17 }
18}
19
20impl Data for Bytes {
22 fn slice<R: RangeBounds<usize>>(&self, r: R) -> &[u8] {
23 let r = translate_range(0, self.len(), r);
24 &self.chunk()[r]
25 }
26
27 fn view<R: RangeBounds<usize>>(&self, r: R) -> Self {
28 self.slice(r)
29 }
30
31 fn len(&self) -> usize {
32 self.len()
33 }
34}
35
36#[derive(Clone)]
38pub struct RefData<'s> {
39 pub(crate) data: &'s [u8],
40 pub(crate) start: usize,
41 pub(crate) end: usize, }
43
44impl<'s> RefData<'s> {
45 pub fn new(data: &[u8]) -> RefData {
46 RefData {
47 data,
48 start: 0,
49 end: data.len(),
50 }
51 }
52}
53
54impl<'s> Data for RefData<'s> {
55 fn slice<R: RangeBounds<usize>>(&self, r: R) -> &[u8] {
56 let r = translate_range(self.start, self.end, r);
57 &self.data[r]
58 }
59
60 fn view<R: RangeBounds<usize>>(&self, r: R) -> RefData<'s> {
61 let r = translate_range(self.start, self.end, r);
62 RefData {
63 data: self.data,
64 start: r.start,
65 end: r.end,
66 }
67 }
68
69 fn len(&self) -> usize {
70 self.end - self.start
71 }
72}
73
74impl<'s> FrameReader for RefData<'s> {
75 type OwnedType = Bytes;
76
77 fn exposed_data(&self) -> &[u8] {
78 self.slice(..)
79 }
80
81 fn whole_data(&self) -> &[u8] {
82 self.slice(..)
83 }
84
85 fn to_owned_frame(&self) -> Self::OwnedType {
86 panic!(
87 "Cannot call to_owned_frame since it could copy unbounded amount of referenced bytes"
88 )
89 }
90}
91
92#[cfg(feature = "mmap")]
94pub use mmap::*;
95
96#[cfg(feature = "mmap")]
97mod mmap {
98 use std::{ops::RangeBounds, sync::Arc};
99
100 use bytes::Bytes;
101 use exocore_core::framing::FrameReader;
102
103 use super::{translate_range, Data};
104
105 #[derive(Clone)]
106 pub struct MmapData {
107 pub(crate) data: Arc<memmap2::Mmap>,
108 pub(crate) start: usize,
109 pub(crate) end: usize, }
111
112 impl MmapData {
113 pub fn from_mmap(data: Arc<memmap2::Mmap>, len: usize) -> MmapData {
114 MmapData {
115 data,
116 start: 0,
117 end: len,
118 }
119 }
120 }
121
122 impl Data for MmapData {
123 fn slice<R: RangeBounds<usize>>(&self, r: R) -> &[u8] {
124 let r = translate_range(self.start, self.end, r);
125 &self.data[r]
126 }
127
128 fn view<R: RangeBounds<usize>>(&self, r: R) -> MmapData {
129 let r = translate_range(self.start, self.end, r);
130 MmapData {
131 data: self.data.clone(),
132 start: r.start,
133 end: r.end,
134 }
135 }
136
137 fn len(&self) -> usize {
138 self.end - self.start
139 }
140 }
141
142 impl FrameReader for MmapData {
143 type OwnedType = Bytes;
144
145 fn exposed_data(&self) -> &[u8] {
146 self.slice(..)
147 }
148
149 fn whole_data(&self) -> &[u8] {
150 self.slice(..)
151 }
152
153 fn to_owned_frame(&self) -> Self::OwnedType {
154 panic!("Cannot call to_owned_frame since it could be a whole mmap file")
155 }
156 }
157}
158
159fn translate_range<R: RangeBounds<usize>>(start: usize, end: usize, range: R) -> Range<usize> {
160 let new_start = match range.start_bound() {
161 Bound::Included(s) => start + *s,
162 Bound::Excluded(s) => start + *s + 1,
163 Bound::Unbounded => start,
164 };
165 let new_end = match range.end_bound() {
166 Bound::Included(s) => (start + *s + 1).min(end),
167 Bound::Excluded(s) => (start + *s).min(end),
168 Bound::Unbounded => end,
169 };
170
171 Range {
172 start: new_start,
173 end: new_end,
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
182 fn test_translate_range() {
183 assert_eq!(translate_range(0, 99, ..), Range { start: 0, end: 99 });
184 assert_eq!(translate_range(2, 99, ..), Range { start: 2, end: 99 });
185 assert_eq!(translate_range(2, 99, ..120), Range { start: 2, end: 99 });
186 assert_eq!(translate_range(10, 99, 0..9), Range { start: 10, end: 19 });
187 assert_eq!(translate_range(10, 99, 0..=9), Range { start: 10, end: 20 });
188 assert_eq!(translate_range(10, 99, ..9), Range { start: 10, end: 19 });
189 assert_eq!(translate_range(10, 99, ..10), Range { start: 10, end: 20 });
190 assert_eq!(translate_range(10, 99, 80..), Range { start: 90, end: 99 });
191 }
192}