arduino-emulator
Loading...
Searching...
No Matches
StdioDevice.h
1/*
2 StdioDevice.h
3 Copyright (c) 2025 Phil Schatzmann. All right reserved.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19#pragma once
20
21#include <iostream>
22#include <cstring>
23#include <algorithm>
24#include <deque>
25#if defined(__unix__) || defined(__APPLE__)
26#include <sys/ioctl.h>
27#include <unistd.h>
28#endif
29#include <streambuf>
30#include "api/Stream.h"
31#include "api/Printable.h"
32
33namespace arduino {
34
51class StdioDevice : public Stream {
52 public:
53 StdioDevice(bool autoFlush = true) { auto_flush = autoFlush; }
54
55 ~StdioDevice() {}
56
57 operator bool() const {
58 return true;
59 } // For classic while(!Serial) { ... } pattern for USB ready wait
60
61 virtual void begin(int speed) {
62 // nothing to be done
63 }
64
65 // Keep all of Print's overloads (double, long, unsigned, char, ...)
66 // visible: declaring print()/println() here would otherwise hide them,
67 // silently routing e.g. print(3.14, 2) to print(int, radix).
68 using Stream::print;
69 using Stream::println;
70
71 virtual size_t print(const char* str) {
72 std::cout << str;
73 if (auto_flush) flush();
74 return strlen(str);
75 }
76
77 virtual size_t println() { return println(""); }
78
79 virtual size_t println(const char* str) {
80 std::cout << str << "\n";
81 if (auto_flush) flush();
82 return strlen(str) + 1;
83 }
84
85 virtual size_t print(int val, int radix = DEC) {
86 size_t result = Stream::print(val, radix);
87 if (auto_flush) flush();
88 return result;
89 }
90
91 virtual size_t println(int val, int radix = DEC) {
92 size_t result = Stream::println(val, radix);
93 if (auto_flush) flush();
94 return result;
95 }
96
97 virtual size_t println(String& str) { return println(str.c_str()); }
98
99 virtual size_t print(String& str) { return print(str.c_str()); }
100
101 virtual size_t println(Printable& p) {
102 size_t result = p.printTo(*this);
103 std::cout << "\n";
104 if (auto_flush) flush();
105 return result + 1;
106 }
107
108 virtual size_t print(Printable& p) {
109 auto result = p.printTo(*this);
110 if (auto_flush) flush();
111 return result;
112 }
113
114 void flush() override { std::cout.flush(); }
115
116 virtual size_t write(const char* str, size_t len) {
117 std::cout.write(str, len);
118 if (auto_flush) flush();
119 return len;
120 }
121
122 virtual size_t write(uint8_t* str, size_t len) {
123 std::cout.write((const char*)str, len);
124 if (auto_flush) flush();
125 return len;
126 }
127 size_t write(const uint8_t* str, size_t len) override {
128 std::cout.write((const char*)str, len);
129 if (auto_flush) flush();
130 return len;
131 }
132
133 virtual size_t write(int32_t value) {
134 std::cout.put(value);
135 if (auto_flush) flush();
136 return 1;
137 }
138
139 size_t write(uint8_t value) override {
140 std::cout.put(value);
141 if (auto_flush) flush();
142 return 1;
143 }
144
145 int available() override {
146#if defined(__unix__) || defined(__APPLE__)
147 fillInputBuffer();
148 return static_cast<int>(inputBuffer_.size());
149#endif
150 return std::cin.rdbuf()->in_avail();
151 }
152
153 int read() override {
154#if defined(__unix__) || defined(__APPLE__)
155 if (available() == 0) return -1;
156 const int value = inputBuffer_.front();
157 inputBuffer_.pop_front();
158 return value;
159#else
160 return std::cin.get();
161#endif
162 }
163
164 int peek() override {
165#if defined(__unix__) || defined(__APPLE__)
166 return available() > 0 ? inputBuffer_.front() : -1;
167#else
168 return std::cin.peek();
169#endif
170 }
171
172 protected:
173 bool auto_flush = true;
174
175#if defined(__unix__) || defined(__APPLE__)
176 private:
177 void fillInputBuffer() {
178 int byteCount = 0;
179 if (ioctl(STDIN_FILENO, FIONREAD, &byteCount) != 0 || byteCount <= 0) {
180 return;
181 }
182
183 char buffer[256];
184 const size_t bytesToRead = std::min(static_cast<size_t>(byteCount), sizeof(buffer));
185 const ssize_t bytesRead = ::read(STDIN_FILENO, buffer, bytesToRead);
186 if (bytesRead <= 0) {
187 return;
188 }
189 inputBuffer_.insert(inputBuffer_.end(), buffer, buffer + bytesRead);
190 }
191
192 std::deque<unsigned char> inputBuffer_;
193#endif
194};
195
196inline StdioDevice Serial;
197#ifndef USE_RPI
198inline StdioDevice Serial2;
199#endif
200
201} // namespace arduino
Definition DMAPool.h:103
Definition Printable.h:35
Provides a Stream interface for standard input/output operations outside the Arduino environment.
Definition StdioDevice.h:51
Definition Stream.h:51
Definition String.h:53
We provide the WiFi class to simulate the Arduino WIFI. In in Linux we can expect that networking is ...
Definition CanMsg.cpp:31