rust_rsm/common/
ringbuf.rs1#![allow(non_camel_case_types)]
2#![allow(non_snake_case)]
3#![allow(non_upper_case_globals)]
4
5use std::{cmp,alloc,mem,ptr};
8use super::errcode;
9
10pub type fn_check_msg_interity=fn(start_bytes:&[u8],req_size:usize,total:usize)->Result<usize,errcode::RESULT>;
13
14pub struct ring_buffer_t {
15 buffer:*mut u8,
16 size:usize,
17 head:usize,
18 tail:usize,
19 fn_call_back:Option<fn_check_msg_interity>,
20}
21
22
23impl ring_buffer_t {
25 pub fn new(capacity:usize,call_back:Option<fn_check_msg_interity>)->Option<Self> {
26 let p=unsafe { alloc::alloc(alloc::Layout::from_size_align_unchecked(capacity, 1)) };
27 if p.is_null() {
28 return None
29 }
30 return Some(Self {
31 buffer:p,
32 size:capacity,
33 head:usize::MAX,
34 tail:0,
35 fn_call_back:call_back,
36 })
37 }
38
39 pub fn len(&self)->usize {
40 if self.head==usize::MAX {
41 return 0
42 }
43 if self.head==self.tail {
44 return self.size
45 }
46 (self.tail+self.size-self.head) % self.size
47 }
48
49 pub fn buffer_available(&self)->usize {
50 self.size-self.len()
51 }
52
53 pub fn put_data(&mut self,buf:&[u8])->errcode::RESULT {
55 if buf.len()>self.buffer_available() {
56 return errcode::ERROR_OUTOF_MEM
57 }
58 if buf.len()==0 {
59 return errcode::ERROR_NO_DATA
60 }
61 let first_slice_len=cmp::min(buf.len(),self.size-self.tail);
62 unsafe {
63 if first_slice_len>=buf.len() {
64 ptr::copy_nonoverlapping(buf.as_ptr(), self.buffer.offset(self.tail as isize), buf.len());
65 } else {
66 ptr::copy_nonoverlapping(buf.as_ptr(), self.buffer.offset(self.tail as isize), first_slice_len);
67 ptr::copy_nonoverlapping(buf[first_slice_len..].as_ptr(), self.buffer, buf.len()-first_slice_len);
68 }
69 }
70 if self.head==usize::MAX {
71 self.head=self.tail;
72 }
73 self.tail=(self.tail+buf.len()) % self.size;
74
75 errcode::RESULT_SUCCESS
76 }
77
78 fn copy_data_uncheck(&self,offset:usize,copy_len:usize,buf:&mut [u8]) {
80 let index=(self.head+offset) % self.size;
81 let first_slice_len = if index>self.tail {
82 cmp::min(copy_len,self.size-index)
83 } else {
84 copy_len
85 };
86 unsafe {
87 if first_slice_len==copy_len {
88 ptr::copy_nonoverlapping(self.buffer.offset(index as isize), buf.as_mut_ptr(),copy_len);
89 } else {
90 ptr::copy_nonoverlapping(self.buffer.offset(index as isize), buf.as_mut_ptr(), first_slice_len);
91 ptr::copy_nonoverlapping(self.buffer, buf[first_slice_len..].as_mut_ptr(),copy_len-first_slice_len);
92 }
93 }
94 }
95 pub fn pull_data(&mut self,max_len:usize,buf:&mut [u8])->Result<usize,errcode::RESULT> {
97 if self.len()==0 {
98 return Err(errcode::ERROR_NO_DATA)
99 }
100 if buf.len()==0 {
101 return Err(errcode::ERROR_BUFFER_TOO_SMALL)
102 }
103 let req_len = cmp::min(max_len, buf.len());
104 let data_len = match self.fn_call_back {
105 None=> {
106 cmp::min(req_len, self.len())
107 },
108 Some(fn_cb)=>{
109 let mut hdr=[0u8;8];
110 let l=match self.peek_data(0, hdr.len(), &mut hdr) {
111 Ok(l)=>l,
112 Err(e)=>return Err(e),
113 };
114
115 if let Ok(len)= fn_cb(&hdr[0..l],req_len,self.len()) {
116 len
117 } else {
118 return Err(errcode::ERROR_NO_OP)
119 }
120 },
121 };
122
123 self.copy_data_uncheck(0,data_len,buf);
124 if self.len()<=data_len {
125 self.tail=0;
126 self.head=usize::MAX;
127 } else {
128 self.head=(self.head+data_len) % self.size;
129 }
130
131 Ok(data_len)
132 }
133 pub fn peek_data(&self,offset:usize,max_len:usize,buf:&mut [u8])->Result<usize,errcode::RESULT> {
135 if offset>=self.len() {
136 return Err(errcode::ERROR_NO_DATA)
137 }
138
139 let copy_len=cmp::min(self.len()-offset,cmp::min(max_len,buf.len()));
140 self.copy_data_uncheck(offset,copy_len, buf);
141
142 Ok(copy_len)
143 }
144
145}
146
147impl Drop for ring_buffer_t {
148 fn drop(&mut self) {
149 if self.buffer.is_null() {
150 return
151 }
152 unsafe {
153 alloc::dealloc(self.buffer, alloc::Layout::from_size_align_unchecked(self.size, 1));
154 self.buffer=ptr::null_mut();
155 }
156 }
157}
158
159use super::spin_lock_t;
160pub struct ts_ring_buffer_t {
161 lock:spin_lock_t,
162 ring:ring_buffer_t,
163}
164
165impl ts_ring_buffer_t {
167 pub fn new(capacity:usize,call_back:Option<fn_check_msg_interity>)->Option<Self> {
168 let ring=ring_buffer_t::new(capacity, call_back);
169 match ring {
170 None=>return None,
171 Some(r)=>{
172 return Some(Self { lock: spin_lock_t::new(), ring: r })
173 }
174 }
175
176 }
177
178 pub fn len(&self)->usize {
179 self.lock.lock();
180 let l=self.ring.len();
181 self.lock.unlock();
182 l
183 }
184
185 pub fn buffer_available(&self)->usize {
186 self.lock.lock();
187 let r=self.ring.buffer_available();
188 self.lock.unlock();
189 r
190 }
191
192 pub fn put_data(&mut self,buf:&[u8])->errcode::RESULT {
193 self.lock.lock();
194 let r=self.ring.put_data(buf);
195 self.lock.unlock();
196 r
197 }
198 pub fn pull_data(&mut self,max_len:usize,buf:&mut [u8])->Result<usize,errcode::RESULT> {
199 self.lock.lock();
200 let r=self.ring.pull_data(max_len, buf);
201 self.lock.unlock();
202 r
203 }
204
205 pub fn peek_data(&self,offset:usize,max_len:usize,buf:&mut [u8])->Result<usize,errcode::RESULT> {
206 self.lock.lock();
207 let r=self.ring.peek_data(offset, max_len, buf);
208 self.lock.unlock();
209 r
210 }
211
212}