ring_buffer.c
Go to the documentation of this file.
1 /*
2  * ring_buffer.c
3  *
4  * Created on: May 5, 2011
5  * Author: waltj
6  */
7 
8 #include <string.h>
9 
10 #include "ring_buffer.h"
11 
12  //_____ D E F I N I T I O N S ______________________________________________
13 
14  //_____ G L O B A L S ______________________________________________________
15 
16 
17  //_____ L O C A L P R O T O T Y P E S ____________________________________
18 
19 unsigned char* ringfindChar(unsigned char* bufPtr, unsigned char* endPtr, unsigned char character);
20 unsigned char* ringfindChar2(unsigned char* bufPtr, unsigned char* endPtr, unsigned char character1, unsigned char character2);
21 
22 
23 //_____ F U N C T I O N S __________________________________________________
24 
25 
29 void ringBufInit(ring_buf_t *rbuf, unsigned char* buf, int bufSize, int wordByteSize)
30 {
31  rbuf->startPtr = buf;
32  rbuf->endPtr = buf + bufSize;
33  rbuf->rdPtr = buf;
34  rbuf->wrPtr = buf;
35  rbuf->bufSize = bufSize;
36  rbuf->wordByteSize = wordByteSize;
37 }
38 
39 
43 int ringBufUsed(const ring_buf_t *rbuf)
44 {
45  int bytesUsed;
46 
47  bytesUsed = (int)(rbuf->wrPtr - rbuf->rdPtr);
48 
49  // Handle wrapping
50  if (bytesUsed < 0)
51  bytesUsed += rbuf->bufSize;
52 
53  return bytesUsed;
54 }
55 
56 
61 int ringBufFree(const ring_buf_t *rbuf)
62 {
63  return (rbuf->bufSize - rbuf->wordByteSize - ringBufUsed(rbuf));
64 }
65 
66 
76 int ringBufWrite(ring_buf_t *rb, unsigned char *buf, int numBytes)
77 {
78  if (numBytes <= 0)
79  return 0;
80 
81  int overflow = numBytes > ringBufFree(rb);
82 
83  // Copy data into buffer
84  while (numBytes>0)
85  {
86  // Bytes before wrap is needed
87  int bytesToEnd = (int)(rb->endPtr - rb->wrPtr);
88 
89  if (numBytes >= bytesToEnd)
90  { // Wrap needed
91 
92  // Copy data to end of buffer
93  memcpy((void *)rb->wrPtr, (void *)buf, bytesToEnd);
94 
95  // Update pointer
96  rb->wrPtr = rb->startPtr;
97 
98  numBytes -= bytesToEnd;
99  }
100  else
101  { // No wrap
102 
103  // Copy data
104  memcpy((void *)rb->wrPtr, (void *)buf, numBytes);
105 
106  // Update pointer
107  rb->wrPtr += numBytes;
108 
109  numBytes = 0;
110  }
111  }
112 
113  if (overflow)
114  { // Move read pointer for overflow
115  rb->rdPtr = rb->wrPtr + rb->wordByteSize;
116 
117  if (rb->rdPtr >= rb->endPtr)
118  { // Handle wrap
119  rb->rdPtr = rb->startPtr;
120  }
121  }
122 
123  return overflow;
124 }
125 
126 
136 int ringBufRead(ring_buf_t *rbuf, unsigned char *buf, int len)
137 {
138  int bytesToRead, bytesRead1, bytesRead2;
139 
140  if ((bytesToRead = ringBufUsed(rbuf)) <= 0)
141  return 0; // Buffer empty
142 
143  if (len < bytesToRead)
144  bytesToRead = len;
145 
146  // Will Data Read Need to Wrap?
147  // If ( used part of Rx buffer wraps && data to be read is more than to buffer's end )
148  if (rbuf->rdPtr > rbuf->wrPtr && bytesToRead > rbuf->endPtr - rbuf->rdPtr)
149  { // Yes Wrapping
150  // Bytes until end of buffer
151  bytesRead1 = (int)(rbuf->endPtr - rbuf->rdPtr);
152  bytesRead2 = (int)(bytesToRead - bytesRead1);
153 
154  // Copy Data into Rx buffer
155  memcpy((void *)buf, (void *)rbuf->rdPtr, bytesRead1); // Read to end
156  memcpy((void *)&buf[bytesRead1], (void *)rbuf->startPtr, bytesRead2); // Read starting at beginning
157 
158  // Update pointer
159  rbuf->rdPtr = rbuf->startPtr + bytesRead2;
160  }
161  else
162  { // No Wrapping
163  // Read data out of Rx buffer
164  memcpy(buf, (void *)rbuf->rdPtr, bytesToRead);
165 
166  // Update pointer
167  rbuf->rdPtr += bytesToRead;
168 
169  // Reset read pointer to buffer start (in case it reached end)
170  if (rbuf->rdPtr >= rbuf->endPtr)
171  rbuf->rdPtr = rbuf->startPtr;
172  }
173 
174  return bytesToRead;
175 }
176 
177 
188 int ringBufPeek(const ring_buf_t *rbuf, unsigned char *buf, int len, int offset)
189 {
190  int bytesToRead, bytesRead1, bytesRead2;
191  int bytesUsed = ringBufUsed(rbuf);
192 
193  if ((bytesToRead = bytesUsed) <= 0)
194  return 0; // Buffer empty
195 
196  // Validate byte offset
197  if (offset >= bytesUsed)
198  return 0;
199 
200  if (len < bytesToRead)
201  bytesToRead = len;
202 
203  unsigned char *rdPtr = rbuf->rdPtr + offset;
204  // Handle read pointer wrapping
205  if (rdPtr >= rbuf->endPtr) {
206  rdPtr -= rbuf->bufSize;
207  }
208 
209  // Will Data Read Need to Wrap?
210  // If ( used part of Rx buffer wraps && data to be read is more than to buffer's end )
211  if (rdPtr > rbuf->wrPtr && bytesToRead > rbuf->endPtr - rdPtr)
212  { // Yes Wrapping
213  // Bytes until end of buffer
214  bytesRead1 = (int)(rbuf->endPtr - rdPtr);
215  bytesRead2 = (int)(bytesToRead - bytesRead1);
216 
217  // Copy Data into Rx buffer
218  memcpy((void *)buf, (void *)rdPtr, bytesRead1); // Read to end
219  memcpy((void *)&buf[bytesRead1], (void *)rbuf->startPtr, bytesRead2); // Read starting at beginning
220  }
221  else
222  { // No Wrapping
223  // Read data out of Rx buffer
224  memcpy(buf, (void *)rdPtr, bytesToRead);
225  }
226 
227  return bytesToRead;
228 }
229 
230 
240 unsigned char* ringfindChar(unsigned char* bufPtr, unsigned char* endPtr, unsigned char character)
241 {
242  // Search for character
243  for (; bufPtr < endPtr; bufPtr++)
244  {
245  // Check for match
246  if (*bufPtr == character)
247  return bufPtr + 1;
248  }
249 
250  return 0;
251 }
252 
253 
263 unsigned char* ringfindChar2(unsigned char* bufPtr, unsigned char* endPtr, unsigned char character1, unsigned char character2)
264 {
265  // Search for character
266  for (; bufPtr < endPtr; bufPtr++)
267  {
268  // Check for match
269  if (*bufPtr == character1 || *bufPtr == character2)
270  return bufPtr + 1;
271  }
272 
273  return 0;
274 }
275 
276 
288 int ringBufReadToChar(ring_buf_t *rbuf, unsigned char *buf, int len, unsigned char character)
289 {
290  return ringBufReadToChar2(rbuf, buf, len, character, character);
291 }
292 
293 
306 int ringBufReadToChar2(ring_buf_t *rbuf, unsigned char *buf, int len, unsigned char character1, unsigned char character2)
307 {
308  int bytesToRead, bytesRead1, bytesRead2;
309  unsigned char* fndPtr;
310 
311  if ((bytesToRead = ringBufUsed(rbuf)) <= 0)
312  return 0; // Buffer empty
313 
314  if (len < bytesToRead)
315  bytesToRead = len;
316 
317  // Will Data Search and Read Need to Wrap?
318  // If ( used part of Rx buffer wraps && data to be read is more than to buffer's end )
319  if (rbuf->rdPtr > rbuf->wrPtr && bytesToRead > rbuf->endPtr - rbuf->rdPtr)
320  {
321  // Yes, Wrapping in Search
322 
323  // Search up to buffer end (before wrapping)
324  if ((fndPtr = ringfindChar2(rbuf->rdPtr, rbuf->endPtr, character1, character2)) <= (unsigned char*)0)
325  {
326  // Not found - Search from start
327  // Bytes until end of buffer
328  bytesRead1 = (int)(rbuf->endPtr - rbuf->rdPtr);
329  bytesRead2 = (int)(bytesToRead - bytesRead1);
330 
331  if ((fndPtr = ringfindChar2(rbuf->startPtr, rbuf->startPtr + bytesRead2, character1, character2)) <= (unsigned char*)0)
332  {
333  // Character NOT found
334  return 0;
335  }
336  else
337  {
338  // Found character - Wrapping Needed
339  bytesRead2 = (int)(fndPtr - rbuf->startPtr);
340 
341  // Copy Data into Rx buffer
342  memcpy((void *)buf, (void *)rbuf->rdPtr, bytesRead1); // Read to end
343  memcpy((void *)&buf[bytesRead1], (void *)rbuf->startPtr, bytesRead2); // Read starting at beginning
344 
345  // Update pointer
346  rbuf->rdPtr = rbuf->startPtr + bytesRead2;
347 
348  return bytesRead1 + bytesRead2;
349  }
350  }
351  }
352  else
353  { // No Wrapping in Search
354  if ((fndPtr = ringfindChar2(rbuf->rdPtr, rbuf->rdPtr + bytesToRead, character1, character2)) <= (unsigned char*)0)
355  { // Character NOT found
356  return 0;
357  }
358  }
359 
360  // Found character - No Wrapping
361  bytesToRead = (int)(fndPtr - rbuf->rdPtr);
362 
363  // Read data out of Rx buffer
364  memcpy(buf, rbuf->rdPtr, bytesToRead);
365 
366  // Update pointer
367  rbuf->rdPtr += bytesToRead;
368 
369  // Reset read pointer to buffer start (in case it reached end)
370  if (rbuf->rdPtr >= rbuf->endPtr)
371  rbuf->rdPtr = rbuf->startPtr;
372 
373  return bytesToRead;
374 }
375 
376 
387 int ringBufFind(const ring_buf_t *rbuf, const unsigned char *str, int len)
388 {
389  int i;
390  int used = ringBufUsed(rbuf);
391  // int bytesToEnd = rbuf->endPtr - rbuf->rdPtr;
392 
393  unsigned char *buf = (unsigned char*)(rbuf->rdPtr);
394 
395  for (i = 0; i < used; i++)
396  {
397  if (buf + len >= rbuf->endPtr)
398  {
399  // Handle wrapping
400  int len1 = (int)(buf + len - rbuf->endPtr);
401  int len2 = len - len1;
402 
403  if (!strncmp((const char*)buf, (const char*)str, len1) && !strncmp((const char*)buf, (const char*)rbuf->startPtr, len2))
404  return i;
405  }
406  else
407  {
408  // Not Wrapping
409  if (!strncmp((const char*)buf, (const char*)str, len))
410  return i;
411  }
412 
413  buf++;
414 
415  // Handling wrapping
416  if (buf >= rbuf->endPtr)
417  buf = rbuf->startPtr;
418  }
419 
420  return -1;
421 }
422 
423 
432 int ringBufRemove(ring_buf_t *rbuf, int len)
433 {
434  int bytesToRemove;
435 
436  if ((bytesToRemove = ringBufUsed(rbuf)) <= 0)
437  {
438  return 0; // Buffer empty
439  }
440 
441  if (len >= bytesToRemove)
442  { // Empty buffer
443  rbuf->rdPtr = rbuf->wrPtr;
444 
445  // Return number bytes removed
446  return bytesToRemove;
447  }
448  else
449  { // Leave some data in buffer
450  rbuf->rdPtr += len;
451 
452  // Handle wrapping
453  if (rbuf->rdPtr >= rbuf->endPtr)
454  rbuf->rdPtr -= rbuf->bufSize;
455 
456  // Return number bytes removed
457  return len;
458  }
459 }
460 
461 
468 {
469  int used = ringBufUsed(rbuf);
470 
471  // Clear all
472  rbuf->rdPtr = rbuf->wrPtr = rbuf->startPtr;
473 
474  return used;
475 }
476 
477 
481 int ringBufEmpty(const ring_buf_t *rbuf)
482 {
483  return ringBufUsed(rbuf) == 0;
484 }
unsigned char * ringfindChar2(unsigned char *bufPtr, unsigned char *endPtr, unsigned char character1, unsigned char character2)
This function returns a pointer to one past the first occurrence of the character in the string...
Definition: ring_buffer.c:263
int ringBufUsed(const ring_buf_t *rbuf)
This function returns the number of bytes currently in ring buffer.
Definition: ring_buffer.c:43
int wordByteSize
Definition: ring_buffer.h:25
uint32_t used
Definition: USBD.h:95
unsigned char * endPtr
Definition: ring_buffer.h:21
void ringBufInit(ring_buf_t *rbuf, unsigned char *buf, int bufSize, int wordByteSize)
Initialize ring buffer pointers.
Definition: ring_buffer.c:29
unsigned char * startPtr
Definition: ring_buffer.h:20
int ringBufReadToChar2(ring_buf_t *rbuf, unsigned char *buf, int len, unsigned char character1, unsigned char character2)
This function returns everything up to and including the first occurrence of a character. If the character is not found, then nothing (zero) is returned.
Definition: ring_buffer.c:306
int ringBufClear(ring_buf_t *rbuf)
Clear the entire buffer.
Definition: ring_buffer.c:467
unsigned char * ringfindChar(unsigned char *bufPtr, unsigned char *endPtr, unsigned char character)
This function returns a pointer to one past the first occurrence of the character in the string...
Definition: ring_buffer.c:240
int ringBufRemove(ring_buf_t *rbuf, int len)
This function removes data from the ring buffer.
Definition: ring_buffer.c:432
int ringBufReadToChar(ring_buf_t *rbuf, unsigned char *buf, int len, unsigned char character)
This function returns everything up to and including the first occurrence of a character. If the character is not found, then nothing (zero) is returned.
Definition: ring_buffer.c:288
int ringBufPeek(const ring_buf_t *rbuf, unsigned char *buf, int len, int offset)
This function reads data from the ring buffer without removing any data. Same as ringBufPop without m...
Definition: ring_buffer.c:188
int ringBufRead(ring_buf_t *rbuf, unsigned char *buf, int len)
This function reads data from the ring buffer.
Definition: ring_buffer.c:136
int ringBufWrite(ring_buf_t *rb, unsigned char *buf, int numBytes)
This function writes data to the ring buffer.
Definition: ring_buffer.c:76
int ringBufEmpty(const ring_buf_t *rbuf)
This function returns 1 if the buffer is empty, 0 if not empty.
Definition: ring_buffer.c:481
unsigned char * rdPtr
Definition: ring_buffer.h:22
int ringBufFree(const ring_buf_t *rbuf)
This function returns the number of bytes free in UART Rx buffer. Important: Buffer size is one less ...
Definition: ring_buffer.c:61
int ringBufFind(const ring_buf_t *rbuf, const unsigned char *str, int len)
This function finds the index of the first matching string in the ring buffer. Returns -1 if not foun...
Definition: ring_buffer.c:387
unsigned char * wrPtr
Definition: ring_buffer.h:23


inertial_sense_ros
Author(s):
autogenerated on Sun Feb 28 2021 03:17:58