forked from RebelTechnology/OpenWare
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SerialBuffer.hpp
133 lines (127 loc) · 2.86 KB
/
SerialBuffer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef _SerialBuffer_hpp_
#define _SerialBuffer_hpp_
#include <stdint.h>
#include <string.h> // for memcpy
template<size_t size, typename T = uint8_t>
class SerialBuffer {
private:
volatile size_t writepos = 0;
volatile size_t readpos = 0;
T buffer[size];
public:
size_t getCapacity(){
return size;
}
void push(T* data, size_t len){
T* dest = getWriteHead();
size_t rem = size-writepos;
if(len >= rem){
memcpy(dest, data, rem);
// note that len-rem may be zero
memcpy(buffer, data+rem, len-rem);
writepos = len-rem;
}else{
memcpy(dest, data, len);
writepos += len;
}
}
void pull(T* data, size_t len){
T* src = getReadHead();
size_t rem = size-readpos;
if(len >= rem){
memcpy(data, src, rem);
// note that len-rem may be zero
memcpy(data+rem, buffer, len-rem);
readpos = len-rem;
}else{
memcpy(data, src, len);
readpos += len;
}
}
void push(T c){
buffer[writepos] = c;
writepos = (writepos + 1) % size;
}
T pull(){
T c = buffer[readpos];
readpos = (readpos + 1) % size;
return c;
}
void skipUntilLast(char c){
T* src = getReadHead();
size_t rem = size-readpos;
for(size_t i=0; i<rem; ++i){
if(src[i] != c){
readpos += i;
return;
}
}
rem = writepos;
for(size_t i=0; i<rem; ++i){
if(buffer[i] != c){
readpos = i;
return;
}
}
}
size_t getWriteIndex(){
return writepos;
}
void setWriteIndex(size_t pos){
writepos = pos;
}
T* getWriteHead(){
return buffer+writepos;
}
void incrementWriteHead(size_t len){
// ASSERT((writepos >= readpos && writepos+len <= size) ||
// (writepos < readpos && writepos+len <= readpos), "uart rx overflow");
writepos += len;
if(writepos >= size)
writepos -= size;
}
size_t getReadIndex(){
return readpos;
}
void setReadIndex(size_t pos){
readpos = pos;
}
T* getReadHead(){
return buffer+readpos;
}
void incrementReadHead(size_t len){
// ASSERT((readpos >= writepos && readpos+len <= size) ||
// (readpos < writepos && readpos+len <= writepos), "uart rx underflow");
readpos = (readpos + len) % size;
}
bool notEmpty(){
return writepos != readpos;
}
size_t getReadCapacity(){
return (writepos + size - readpos) % size;
}
size_t getWriteCapacity(){
return size - getReadCapacity();
}
size_t getContiguousWriteCapacity(){
if(writepos < readpos)
return readpos - writepos;
else
return size - writepos;
}
size_t getContiguousReadCapacity(){
if(writepos < readpos)
return size - readpos;
else
return writepos - readpos;
}
void reset(){
readpos = writepos = 0;
setAll(0);
}
void setAll(const T value){
for(size_t i=0; i<size; ++i)
buffer[i] = value;
}
};
#endif /* _SerialBuffer_hpp_ */