1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  *
4  */
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 
11 #include "uvoice_os.h"
12 
13 #include "uvoice_common.h"
14 
15 
uvoice_ringbuff_reset(uvoice_ringbuff_t * rb)16 int32_t uvoice_ringbuff_reset(uvoice_ringbuff_t *rb)
17 {
18 	if (!rb) {
19 		M_LOGE("rb null !\n");
20 		return -1;
21 	}
22 
23 	rb->rd_ptr = rb->buffer;
24 	rb->wr_ptr = rb->buffer;
25 	rb->dirty_size = 0;
26 	rb->free_size = rb->buffer_end - rb->buffer;
27 	return 0;
28 }
29 
uvoice_ringbuff_init(uvoice_ringbuff_t * rb,uint8_t * buffer,int32_t size)30 int32_t uvoice_ringbuff_init(uvoice_ringbuff_t *rb,
31 	uint8_t *buffer, int32_t size)
32 {
33 	if (!rb) {
34 		M_LOGE("rb null !\n");
35 		return -1;
36 	}
37 
38 	if (!buffer) {
39 		M_LOGE("buffer null !\n");
40 		return -1;
41 	}
42 
43 	if (size <= 4) {
44 		M_LOGE("size %d invalid !\n", size);
45 		return -1;
46 	}
47 
48 	rb->buffer = buffer;
49 	rb->buffer_end = rb->buffer + size;
50 	uvoice_ringbuff_reset(rb);
51 	return 0;
52 }
53 
uvoice_ringbuff_freesize(uvoice_ringbuff_t * rb)54 int32_t uvoice_ringbuff_freesize(uvoice_ringbuff_t *rb)
55 {
56 	if (!rb) {
57 		M_LOGE("rb null !\n");
58 		return -1;
59 	}
60 	return rb->free_size;
61 }
62 
uvoice_ringbuff_dirtysize(uvoice_ringbuff_t * rb)63 int32_t uvoice_ringbuff_dirtysize(uvoice_ringbuff_t *rb)
64 {
65 	if (!rb) {
66 		M_LOGE("rb null !\n");
67 		return -1;
68 	}
69 	return rb->dirty_size;
70 }
71 
uvoice_ringbuff_fill(uvoice_ringbuff_t * rb,uint8_t * buffer,int32_t size)72 int32_t uvoice_ringbuff_fill(uvoice_ringbuff_t *rb,
73 	uint8_t *buffer, int32_t size)
74 {
75 	if (!rb) {
76 		M_LOGE("rb null !\n");
77 		return -1;
78 	}
79 
80 	if (size > rb->free_size || size <= 0) {
81 		M_LOGE("size %d invalid !\n", size);
82 		return -1;
83 	}
84 
85 	if ((rb->buffer_end - rb->wr_ptr >= size &&
86 		rb->wr_ptr >= rb->rd_ptr) ||
87 		rb->wr_ptr < rb->rd_ptr) {
88 		memcpy(rb->wr_ptr, buffer, size);
89 		rb->wr_ptr += size;
90 		rb->dirty_size += size;
91 		rb->free_size -= size;
92 		if (rb->wr_ptr >= rb->buffer_end)
93 			rb->wr_ptr = rb->buffer;
94 	} else if (rb->buffer_end - rb->wr_ptr < size &&
95 		rb->wr_ptr >= rb->rd_ptr) {
96 		int temp = rb->buffer_end - rb->wr_ptr;
97 		memcpy(rb->wr_ptr, buffer, temp);
98 		rb->wr_ptr = rb->buffer;
99 		memcpy(rb->wr_ptr, buffer + temp, size - temp);
100 		rb->dirty_size += size;
101 		rb->free_size -= size;
102 		rb->wr_ptr += size - temp;
103 	} else {
104 		M_LOGE("error ! buffer %08x buffer_end %08x rd_ptr %08x wr_ptr %08x dirty %d free %d\n",
105 			(unsigned int)rb->buffer,
106 			(unsigned int)rb->buffer_end,
107 			(unsigned int)rb->rd_ptr,
108 			(unsigned int)rb->wr_ptr, rb->dirty_size, rb->free_size);
109 		return -1;
110 	}
111 
112 	return size;
113 }
114 
uvoice_ringbuff_read(uvoice_ringbuff_t * rb,uint8_t * buffer,int32_t size)115 int32_t uvoice_ringbuff_read(uvoice_ringbuff_t *rb,
116 	uint8_t *buffer, int32_t size)
117 {
118 	if (!rb) {
119 		M_LOGE("rb null !\n");
120 		return -1;
121 	}
122 
123 	if (size > rb->dirty_size || size <= 0) {
124 		M_LOGE("size %d invalid !\n", size);
125 		return -1;
126 	}
127 
128 	if (rb->rd_ptr < rb->wr_ptr &&
129 		rb->wr_ptr - rb->rd_ptr >= size) {
130 		memcpy(buffer, rb->rd_ptr, size);
131 		rb->dirty_size -= size;
132 		rb->free_size += size;
133 		rb->rd_ptr += size;
134 	} else if (rb->rd_ptr >= rb->wr_ptr) {
135 		if (rb->buffer_end - rb->rd_ptr >= size) {
136 			memcpy(buffer, rb->rd_ptr, size);
137 			rb->dirty_size -= size;
138 			rb->free_size += size;
139 			rb->rd_ptr += size;
140 			if (rb->rd_ptr >= rb->buffer_end)
141 				rb->rd_ptr = rb->buffer;
142 		} else {
143 			int temp = rb->buffer_end - rb->rd_ptr;
144 			memcpy(buffer, rb->rd_ptr, temp);
145 			rb->rd_ptr = rb->buffer;
146 			memcpy(buffer + temp, rb->rd_ptr, size - temp);
147 			rb->dirty_size -= size;
148 			rb->free_size += size;
149 			rb->rd_ptr += size - temp;
150 		}
151 	} else {
152 		M_LOGE("error ! buffer %08x buffer_end %08x rd_ptr %08x wr_ptr %08x dirty %d free %d\n",
153 			(unsigned int)rb->buffer,
154 			(unsigned int)rb->buffer_end,
155 			(unsigned int)rb->rd_ptr,
156 			(unsigned int)rb->wr_ptr, rb->dirty_size, rb->free_size);
157 		return -1;
158 	}
159 
160 	return size;
161 }
162 
uvoice_ringbuff_drop(uvoice_ringbuff_t * rb,int32_t size)163 int32_t uvoice_ringbuff_drop(uvoice_ringbuff_t *rb, int32_t size)
164 {
165 	if (!rb) {
166 		M_LOGE("rb null !\n");
167 		return -1;
168 	}
169 
170 	if (size > rb->dirty_size || size <= 0) {
171 		M_LOGE("size %d invalid !\n", size);
172 		return -1;
173 	}
174 
175 	if (rb->wr_ptr - rb->rd_ptr >= size) {
176 		rb->dirty_size -= size;
177 		rb->free_size += size;
178 		rb->rd_ptr += size;
179 		if (rb->rd_ptr >= rb->buffer_end)
180 			rb->rd_ptr = rb->buffer;
181 	} else if (rb->rd_ptr >= rb->wr_ptr) {
182 		if (rb->buffer_end - rb->rd_ptr >= size) {
183 			rb->dirty_size -= size;
184 			rb->free_size += size;
185 			rb->rd_ptr += size;
186 			if (rb->rd_ptr >= rb->buffer_end)
187 				rb->rd_ptr = rb->buffer;
188 		} else {
189 			rb->rd_ptr = rb->buffer +
190 				(size - (rb->buffer_end - rb->rd_ptr));
191 			rb->dirty_size -= size;
192 			rb->free_size += size;
193 		}
194 	} else {
195 		M_LOGE("error ! buffer %08x buffer_end %08x rd_ptr %08x wr_ptr %08x dirty %d free %d\n",
196 			(unsigned int)rb->buffer,
197 			(unsigned int)rb->buffer_end,
198 			(unsigned int)rb->rd_ptr,
199 			(unsigned int)rb->wr_ptr, rb->dirty_size, rb->free_size);
200 		return -1;
201 	}
202 
203 	return 0;
204 }
205 
uvoice_ringbuff_back(uvoice_ringbuff_t * rb,int32_t size)206 int32_t uvoice_ringbuff_back(uvoice_ringbuff_t *rb, int32_t size)
207 {
208 	if (!rb) {
209 		M_LOGE("rb null !\n");
210 		return -1;
211 	}
212 
213 	if (size > rb->free_size || size <= 0) {
214 		M_LOGE("size %d invaid !\n", size);
215 		return -1;
216 	}
217 
218 	if (rb->wr_ptr >= rb->rd_ptr) {
219 		if (rb->rd_ptr - rb->buffer >= size) {
220 			rb->rd_ptr -= size;
221 			rb->free_size -= size;
222 			rb->dirty_size += size;
223 		} else {
224 			rb->rd_ptr = rb->buffer_end -
225 				(size - (rb->rd_ptr - rb->buffer));
226 			rb->free_size -= size;
227 			rb->dirty_size += size;
228 		}
229 	} else {
230 		if (rb->rd_ptr - rb->wr_ptr >= size) {
231 			rb->rd_ptr -= size;
232 			rb->free_size -= size;
233 			rb->dirty_size += size;
234 		} else {
235 			M_LOGE("error ! buffer %08x buffer_end %08x rd_ptr %08x wr_ptr %08x dirty %d free %d\n",
236 				(unsigned int)rb->buffer,
237 				(unsigned int)rb->buffer_end,
238 				(unsigned int)rb->rd_ptr,
239 				(unsigned int)rb->wr_ptr, rb->dirty_size, rb->free_size);
240 			return -1;
241 		}
242 	}
243 
244 	return 0;
245 }
246 
247