forked from bobbrez/WiFly
-
Notifications
You must be signed in to change notification settings - Fork 7
/
ParsedStream.cpp
140 lines (108 loc) · 2.63 KB
/
ParsedStream.cpp
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
134
135
136
137
138
139
140
#include "ParsedStream.h"
void ParsedStream::storeByte(unsigned char c) {
int i = (_rx_buffer.head + 1) % RX_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != _rx_buffer.tail) {
_rx_buffer.buffer[_rx_buffer.head] = c;
_rx_buffer.head = i;
}
}
ParsedStream::ParsedStream()
{
/*
*/
reset();
}
void ParsedStream::begin(Stream* theUart)
{
_uart = theUart;
}
void ParsedStream::reset() {
/*
*/
ring_buffer _rx_buffer = { { 0 }, 0, 0};
_closed = false;
bytes_matched = 0;
}
uint8_t ParsedStream::available(bool raw) {
uint8_t available_bytes;
available_bytes = (RX_BUFFER_SIZE + _rx_buffer.head - _rx_buffer.tail) % RX_BUFFER_SIZE;
if (!raw) {
if (available_bytes > bytes_matched) {
available_bytes -= bytes_matched;
} else {
available_bytes = 0;
}
}
return available_bytes;
}
uint8_t ParsedStream::available() {
// NOTE: This causes a read/buffer fill which isn't entirely
// consistent with how `available()` is normally
// handled.
// TODO: Put this buffer fill in the read section instead?
// TODO: Don't refill if we're almost full and don't have a partial
// match?
while (!_closed && freeSpace() && _uart->available()) {
getByte();
}
return available(false);
}
bool ParsedStream::closed() {
return _closed && !available();
}
int ParsedStream::read(void) {
if (!available()) {
getByte();
}
if (!available()) {
return -1;
} else {
unsigned char c = _rx_buffer.buffer[_rx_buffer.tail];
_rx_buffer.tail = (_rx_buffer.tail + 1) % RX_BUFFER_SIZE;
return c;
}
}
int ParsedStream::peek(void) {
if (!available()) {
getByte();
}
if (!available()) {
return -1;
} else {
unsigned char c = _rx_buffer.buffer[_rx_buffer.tail];
return c;
}
}
int ParsedStream::freeSpace() {
return RX_BUFFER_SIZE - available(true) - 1 /* The -1 fudge due to storeByte calculation*/;
}
void ParsedStream::getByte() {
int c;
if (_closed) {
return;
}
if (freeSpace() == 0) {
return;
}
// TODO: Tidy this...
c = _uart->read();
if (c == -1) {
return;
}
if (c == MATCH_TOKEN[bytes_matched]) {
bytes_matched++;
if (bytes_matched == strlen(MATCH_TOKEN)) {
_closed = true;
}
} else if (c == MATCH_TOKEN[0]) {
// Handle e.g. case "**CLOS*"
bytes_matched = 1;
} else {
bytes_matched = 0;
}
storeByte(c);
}