FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
streambuf.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
21#ifndef STREAMBUF_H
22#define STREAMBUF_H
23
24#include "flash.h"
25#include "interrupts.h"
26#include "queue.h"
27
49#define REGISTER_OSTREAMBUF_LISTENERS(HANDLER1, ...) \
50 void streams::ostreambuf_on_put_dispatch(ostreambuf& obuf) \
51 { \
52 streams::dispatch_handler::ostreambuf_on_put<HANDLER1, ##__VA_ARGS__>(obuf);\
53 }
54
64#define REGISTER_OSTREAMBUF_NO_LISTENERS() \
65 void streams::ostreambuf_on_put_dispatch(ostreambuf&) {}
66
73#define DECL_OSTREAMBUF_LISTENERS_FRIEND \
74 friend struct streams::dispatch_handler;
75
76namespace streams
77{
79 class ostreambuf;
80 extern void ostreambuf_on_put_dispatch(ostreambuf&);
82
95 class ostreambuf : private containers::Queue<char, char>
96 {
97 private:
98 using QUEUE = Queue<char, char>;
99
100 public:
101 ostreambuf(const ostreambuf&) = delete;
102 ostreambuf& operator=(const ostreambuf&) = delete;
103
105 template<uint8_t SIZE>
106 explicit ostreambuf(char (&buffer)[SIZE]) : QUEUE{buffer, true} {}
108
113 void pubsync()
114 {
115 overflow_ = false;
116 while (!empty()) time::yield();
117 }
118
125 void sputc(char c)
126 {
127 put_(c, true);
128 }
129
141 void sputn(const char* content, size_t size)
142 {
143 while (size--) put_(*content++, false);
144 on_put();
145 }
146
158 void sputn(const char* str)
159 {
160 while (*str) put_(*str++, false);
161 on_put();
162 }
163
181 void sputn(const flash::FlashStorage* str)
182 {
183 uint16_t address = (uint16_t) str;
184 while (char value = pgm_read_byte(address++)) put_(value, false);
185 on_put();
186 }
187
194 bool overflow() const
195 {
196 return overflow_;
197 }
198
203 QUEUE& queue()
204 {
205 return *this;
206 }
207
208 protected:
219 void put_(char c, bool call_on_put = true)
220 {
221 if (!push(c)) overflow_ = true;
222 if (call_on_put) on_put();
223 }
224
230 {
231 overflow_ = false;
232 }
233
234 private:
235 void on_put()
236 {
237 ostreambuf_on_put_dispatch(*this);
238 }
239
240 bool overflow_ = false;
241
242 friend class ios_base;
243 friend class ostream;
244 };
245
256 class istreambuf : private containers::Queue<char, char>
257 {
258 private:
259 using QUEUE = Queue<char, char>;
260
261 public:
262 istreambuf(const istreambuf&) = delete;
263 istreambuf& operator=(const istreambuf&) = delete;
264
268 static const int EOF = -1;
269
271 template<uint8_t SIZE> explicit istreambuf(char (&buffer)[SIZE]) : QUEUE{buffer, false} {}
273
277 int in_avail() const
278 {
279 return items();
280 }
281
286 int sbumpc()
287 {
288 char value;
289 if (pull(value)) return value;
290 return EOF;
291 }
292
297 int sgetc()
298 {
299 char value;
300 if (peek(value)) return value;
301 return EOF;
302 }
303
308 QUEUE& queue()
309 {
310 return *this;
311 }
312 };
313
315 struct dispatch_handler
316 {
317 template<bool DUMMY_> static bool ostreambuf_on_put_helper(ostreambuf& obuf UNUSED)
318 {
319 return false;
320 }
321
322 template<bool DUMMY_, typename HANDLER1_, typename... HANDLERS_>
323 static bool ostreambuf_on_put_helper(ostreambuf& obuf)
324 {
325 bool result = interrupt::HandlerHolder<HANDLER1_>::handler()->on_put(obuf);
326 // handle other handlers if needed
327 return result || ostreambuf_on_put_helper<DUMMY_, HANDLERS_...>(obuf);
328 }
329
330 template<typename... HANDLERS_> static void ostreambuf_on_put(ostreambuf& obuf)
331 {
332 // Ask each registered listener tohandle obuf on_put() if concerned
333 ostreambuf_on_put_helper<false, HANDLERS_...>(obuf);
334 }
335 };
337}
338
339#endif /* STREAMBUF_H */
Queue of type T_ items.
Definition: queue.h:59
bool pull(T &item)
Pull an item from the beginning of this queue, if not empty, and copy it into item.
Definition: queue.h:333
bool push(TREF item)
Push item to the end of this queue, provided there is still available space in its ring buffer.
Definition: queue.h:311
bool empty() const
Tell if this queue is currently empty.
Definition: queue.h:420
uint8_t size() const
Get the maximum size of this queue.
Definition: queue.h:219
bool peek(T &item) const
Peek an item from the beginning of this queue, if not empty, and copy it into item.
Definition: queue.h:356
uint8_t items() const
Tell the current number of items currently present in this queue.
Definition: queue.h:432
Input API based on a ring buffer.
Definition: streambuf.h:257
int in_avail() const
Definition: streambuf.h:277
static const int EOF
Special value returned by sbumpc() when buffer is empty.
Definition: streambuf.h:268
QUEUE & queue()
Return the underlying queue.
Definition: streambuf.h:308
Output API based on a ring buffer.
Definition: streambuf.h:96
void pubsync()
Wait until all buffer content has been pulled by a consumer.
Definition: streambuf.h:113
bool overflow() const
Indicate if a buffer overflow has occurred since last time pubsync() or reset_overflow() was called.
Definition: streambuf.h:194
void sputn(const char *str)
Append a string to the buffer.
Definition: streambuf.h:158
void reset_overflow()
Reset the overflow flag.
Definition: streambuf.h:229
void sputn(const flash::FlashStorage *str)
Append a string, stored on flash memory, to the buffer.
Definition: streambuf.h:181
void put_(char c, bool call_on_put=true)
Append a character to the buffer.
Definition: streambuf.h:219
QUEUE & queue()
Return the underlying queue.
Definition: streambuf.h:203
void sputc(char c)
Append a character to the buffer.
Definition: streambuf.h:125
void sputn(const char *content, size_t size)
Append several characters to the buffer.
Definition: streambuf.h:141
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
Flash memory utilities.
General API for handling AVR interrupt vectors.
Defines C++-like streams API, based on circular buffers for input or output.
Definition: empty_streams.h:34
void yield()
Utility method used by many FastArduino API in order to "yield" some processor time; concretely it ju...
Definition: time.cpp:22
Utility API to handle ring-buffer queue containers.