-
Notifications
You must be signed in to change notification settings - Fork 1
/
ParsedStream.cpp
123 lines (92 loc) · 2.4 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
#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(SpiUartDevice& uart) : _uart(uart) {
/*
*/
reset();
}
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::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);
}