My Project
shell_stream.cpp
1 /*
2  * uuid-console - Microcontroller console shell
3  * Copyright 2019,2022 Simon Arlott
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include <uuid/console.h>
20 
21 #include <Arduino.h>
22 
23 namespace uuid {
24 
25 namespace console {
26 
28  if (mode_ == Mode::BLOCKING) {
29  auto *blocking_data = reinterpret_cast<Shell::BlockingData*>(mode_data_.get());
30 
31  if (!stream_.available()) {
32  return 0;
33  }
34 
35  if (blocking_data->consume_line_feed_) {
36  const int input = stream_.peek();
37 
38  if (input >= 0) {
39  const unsigned char c = input;
40 
41  blocking_data->consume_line_feed_ = false;
42 
43  if (previous_ == '\x0D' && c == '\x0A') {
44  // Consume the first LF following a CR
45  stream_.read();
46  previous_ = c;
47  return available();
48  }
49  } else {
50  // The underlying stream has not implemented peek,
51  // so the next read() could return -1 if LF is
52  // filtered out.
53  }
54  }
55 
56  return 1;
57  } else {
58  return 0;
59  }
60 }
61 
62 int Shell::read() {
63  if (mode_ == Mode::BLOCKING) {
64  auto *blocking_data = reinterpret_cast<Shell::BlockingData*>(mode_data_.get());
65  const int input = stream_.read();
66 
67  if (input >= 0) {
68  const unsigned char c = input;
69 
70  if (blocking_data->consume_line_feed_) {
71  blocking_data->consume_line_feed_ = false;
72 
73  if (previous_ == '\x0D' && c == '\x0A') {
74  // Consume the first LF following a CR
75  previous_ = c;
76  return read();
77  }
78  }
79 
80  // Track read characters so that a final CR means we ignore the next LF
81  previous_ = c;
82  }
83 
84  return input;
85  } else {
86  return -1;
87  }
88 }
89 
90 int Shell::peek() {
91  if (mode_ == Mode::BLOCKING) {
92  auto *blocking_data = reinterpret_cast<Shell::BlockingData*>(mode_data_.get());
93  const int input = stream_.peek();
94 
95  if (blocking_data->consume_line_feed_) {
96  if (input >= 0) {
97  const unsigned char c = input;
98 
99  blocking_data->consume_line_feed_ = false;
100 
101  if (previous_ == '\x0D' && c == '\x0A') {
102  // Consume the first LF following a CR
103  stream_.read();
104  previous_ = c;
105  return peek();
106  }
107  }
108  }
109 
110  return input;
111  } else {
112  return -1;
113  }
114 }
115 
116 size_t Shell::write(uint8_t data) {
117  return stream_.write(data);
118 }
119 
120 size_t Shell::write(const uint8_t *buffer, size_t size) {
121  return stream_.write(buffer, size);
122 }
123 
124 
125 void Shell::flush() {
126  // This is a pure virtual function in Arduino's Stream class, which
127  // makes no sense because that class is for input and this is an
128  // output function. Later versions move it to Print as an empty
129  // virtual function so this is here for backward compatibility.
130 }
131 
132 } // namespace console
133 
134 } // namespace uuid
uuid::console::Shell::peek
int peek() final override
Read one byte from the available input without advancing to the next one.
Definition: shell_stream.cpp:90
uuid::console::Shell::flush
void flush() final override
Does nothing.
Definition: shell_stream.cpp:125
uuid::console::Shell::previous_
unsigned char previous_
Definition: console.h:1627
uuid::console::Shell::available
int available() final override
Check for available input.
Definition: shell_stream.cpp:27
uuid::console::Shell::Mode::BLOCKING
@ BLOCKING
uuid::console::Shell::mode_data_
std::unique_ptr< ModeData > mode_data_
Definition: console.h:1629
uuid::console::Shell::read
int read() final override
Read one byte from the available input.
Definition: shell_stream.cpp:62
uuid::console::Shell::stream_
Stream & stream_
Definition: console.h:1615
uuid
Common utilities.
Definition: get_uptime_ms.cpp:28
uuid::console::Shell::BlockingData
Data for the Mode::BLOCKING shell mode.
Definition: console.h:1454
uuid::console::Shell::write
size_t write(uint8_t data) final override
Write one byte to the output stream.
Definition: shell_stream.cpp:116
uuid::console::Shell::mode_
Mode mode_
Definition: console.h:1628