FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
streams.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 STREAMS_HH
22#define STREAMS_HH
23
24#include <ctype.h>
25#include "queue.h"
26#include "flash.h"
27#include "ios.h"
28#include "streambuf.h"
29#include "time.h"
30
55namespace streams
56{
60 class ostream : public ios_base
61 {
62 public:
67 explicit ostream(ostreambuf& streambuf) : streambuf_{streambuf} {}
68
70 ostream(const ostream&) = delete;
71 ostream& operator=(const ostream&) = delete;
73
78 {
79 return streambuf_;
80 }
81
89 void flush()
90 {
91 streambuf_.pubsync();
92 }
93
101 void put(char c)
102 {
103 streambuf_.sputc(c);
104 check_overflow();
105 }
106
116 void write(const char* content, size_t size)
117 {
118 streambuf_.sputn(content, size);
119 check_overflow();
120 }
121
130 void write(const char* str)
131 {
132 streambuf_.sputn(str);
133 check_overflow();
134 }
135
144 void write(const flash::FlashStorage* str)
145 {
146 streambuf_.sputn(str);
147 check_overflow();
148 }
149
160 ostream& operator<<(const void* ptr)
161 {
162 convert(streambuf_, uint16_t(ptr));
163 after_insertion();
164 return *this;
165 }
166
175 ostream& operator<<(bool value)
176 {
177 convert(streambuf_, value);
178 after_insertion();
179 return *this;
180 }
181
191 {
192 convert(streambuf_, ch);
193 after_insertion();
194 return *this;
195 }
196
205 ostream& operator<<(const char* str)
206 {
207 justify(streambuf_, str, false, nullptr);
208 after_insertion();
209 return *this;
210 }
211
220 ostream& operator<<(const flash::FlashStorage* str)
221 {
222 justify(streambuf_, str);
223 after_insertion();
224 return *this;
225 }
226
237 ostream& operator<<(int value)
238 {
239 convert(streambuf_, value);
240 after_insertion();
241 return *this;
242 }
243
254 ostream& operator<<(unsigned int value)
255 {
256 convert(streambuf_, value);
257 after_insertion();
258 return *this;
259 }
260
271 ostream& operator<<(long value)
272 {
273 convert(streambuf_, value);
274 after_insertion();
275 return *this;
276 }
277
288 ostream& operator<<(unsigned long value)
289 {
290 convert(streambuf_, value);
291 after_insertion();
292 return *this;
293 }
294
305 ostream& operator<<(double value)
306 {
307 convert(streambuf_, value);
308 after_insertion();
309 return *this;
310 }
311
315 using MANIPULATOR = void (*)(ostream&);
316
334 {
335 func(*this);
336 return *this;
337 }
338
339 private:
340 void after_insertion()
341 {
342 check_overflow();
343 if (flags() & unitbuf) streambuf_.pubsync();
344 width(0);
345 }
346
347 void check_overflow()
348 {
349 if (streambuf_.overflow()) setstate(badbit);
350 }
351
352 ostreambuf& streambuf_;
353 };
354
355 // NOTE: istream API is blocking, while istreambuf is not
359 class istream : public ios_base
360 {
361 public:
366 explicit istream(istreambuf& streambuf) : streambuf_{streambuf} {}
367
368 istream& operator=(const istream&) = delete;
369
374 {
375 return streambuf_;
376 }
377
384 int peek()
385 {
386 int value;
387 while ((value = streambuf_.sgetc()) == istreambuf::EOF) time::yield();
388 return value;
389 }
390
397 int get()
398 {
399 int value;
400 while ((value = streambuf_.sbumpc()) == istreambuf::EOF) time::yield();
401 return value;
402 }
403
411 istream& get(char& ch)
412 {
413 ch = get();
414 return *this;
415 }
416
425 istream& get(char* str, size_t n, char delim = '\n')
426 {
427 while (--n)
428 {
429 int ch = peek();
430 if (ch == delim) break;
431 *str++ = get();
432 }
433 *str = 0;
434 return *this;
435 }
436
445 istream& getline(char* str, size_t n, char delim = '\n')
446 {
447 while (--n)
448 {
449 int ch = get();
450 if (ch == delim) break;
451 *str++ = ch;
452 }
453 *str = 0;
454 return *this;
455 }
456
464 istream& ignore(size_t n = 1, int delim = istreambuf::EOF)
465 {
466 bool forever = (n == 0);
467 while (forever || (n > 0))
468 {
469 --n;
470 if (get() == delim) break;
471 }
472 return *this;
473 }
474
480 istream& read(char* str, size_t n)
481 {
482 while (n--) *str++ = get();
483 return *this;
484 }
485
498 istream& operator>>(char* buf)
499 {
500 if (width() > 0)
501 {
502 skipws_if_needed();
503 scan(buf, width());
504 width(0);
505 }
506 return *this;
507 }
508
523 istream& operator>>(bool& value)
524 {
525 skipws_if_needed();
526 char buffer[10 + 1];
527 convert(scan(buffer, sizeof buffer), value);
528 return *this;
529 }
530
543 istream& operator>>(char& value)
544 {
545 skipws_if_needed();
546 value = containers::pull(streambuf_.queue());
547 return *this;
548 }
549
562 istream& operator>>(int& value)
563 {
564 skipws_if_needed();
565 char buffer[sizeof(int) * 8 + 1];
566 convert(scan(buffer, sizeof buffer), value);
567 return *this;
568 }
569
582 istream& operator>>(unsigned int& value)
583 {
584 skipws_if_needed();
585 char buffer[sizeof(int) * 8 + 1];
586 convert(scan(buffer, sizeof buffer), value);
587 return *this;
588 }
589
602 istream& operator>>(long& value)
603 {
604 skipws_if_needed();
605 char buffer[sizeof(long) * 8 + 1];
606 convert(scan(buffer, sizeof buffer), value);
607 return *this;
608 }
609
622 istream& operator>>(unsigned long& value)
623 {
624 skipws_if_needed();
625 char buffer[sizeof(long) * 8 + 1];
626 convert(scan(buffer, sizeof buffer), value);
627 return *this;
628 }
629
642 istream& operator>>(double& value)
643 {
644 skipws_if_needed();
645 // Allocate sufficient size for fixed/scientific representation with precision max = 16
646 // Need 1 more for sign, 1 for DP, 1 for first digit, 4 for e+00
647 char buffer[DOUBLE_BUFFER_SIZE];
648 convert(scan(buffer, sizeof buffer), value);
649 return *this;
650 }
651
655 using MANIPULATOR = void (*)(istream&);
656
675 {
676 func(*this);
677 return *this;
678 }
679
680 private:
681 void skipws_if_needed()
682 {
683 if (flags() & skipws) skip_whitespace();
684 }
685
686 void skip_whitespace()
687 {
688 while (isspace(containers::peek(streambuf_.queue()))) containers::pull(streambuf_.queue());
689 }
690
691 char* scan(char* str, size_t max);
692
693 istreambuf& streambuf_;
694
695 template<typename FSTREAM> friend void ws(FSTREAM&);
696 };
697
708 template<typename FSTREAM> inline void ws(FSTREAM& stream)
709 {
710 stream.skip_whitespace();
711 }
712
716 template<typename FSTREAM> inline void flush(FSTREAM& stream)
717 {
718 stream.flush();
719 }
720
725 template<typename FSTREAM> inline void endl(FSTREAM& stream)
726 {
727 stream.put('\n');
728 stream.flush();
729 }
730}
731
732#endif /* STREAMS_HH */
Base class for formatted streams.
Definition: ios.h:38
fmtflags flags() const
Return the format flags currently selected in this stream.
Definition: ios.h:296
void width(uint8_t width)
Set minimum width used for displaying values.
Definition: ios.h:390
static constexpr fmtflags skipws
Skip leading spaces on certain extraction (read) operations.
Definition: ios.h:272
uint8_t width() const
Get the current minimum width value (default = 0) used for formatted output.
Definition: ios.h:400
static constexpr iostate badbit
This bit is set when an irrecoverable stream error has occurred, e.g.
Definition: ios.h:74
void setstate(iostate state)
Set the stream error flags state in addition to currently set flags.
Definition: ios.h:90
static constexpr fmtflags unitbuf
Flush output after each insertion operation.
Definition: ios.h:274
Input stream wrapper to provide formatted input API, a la C++.
Definition: streams.h:360
istream & operator>>(long &value)
Input and interpret next word from buffer as a signed long integer value.
Definition: streams.h:602
istream & ignore(size_t n=1, int delim=istreambuf::EOF)
Extract characters from this input stream and discards them, until either n characters have been extr...
Definition: streams.h:464
istream & read(char *str, size_t n)
Read a block of data from this input stream.
Definition: streams.h:480
int get()
Extract a single character from this input stream.
Definition: streams.h:397
istream(istreambuf &streambuf)
Construct a formatted input wrapper of streambuf.
Definition: streams.h:366
istream & operator>>(bool &value)
Input and interpret next character from buffer as a boolean value.
Definition: streams.h:523
istream & getline(char *str, size_t n, char delim='\n')
Extract characters from this input stream and stores them as a C-string, until either (n - 1) charact...
Definition: streams.h:445
void(*)(istream &) MANIPULATOR
General type of a manipulator function applicable to this input stream.
Definition: streams.h:655
istream & operator>>(char *buf)
Read characters from buffer into buf until one of these conditions happen:
Definition: streams.h:498
istreambuf & rdbuf() const
Return the stream buffer associated with this stream.
Definition: streams.h:373
istream & operator>>(double &value)
Input and interpret next word from buffer as a floating point value.
Definition: streams.h:642
istream & operator>>(unsigned int &value)
Input and interpret next word from buffer as an unsigned integer value.
Definition: streams.h:582
istream & operator>>(unsigned long &value)
Input and interpret next word from buffer as an unsigned long integer value.
Definition: streams.h:622
istream & operator>>(MANIPULATOR func)
Apply a MANIPULATOR to this input stream.
Definition: streams.h:674
istream & get(char &ch)
Extract a single character from this input stream.
Definition: streams.h:411
friend void ws(FSTREAM &)
Manipulator for an input stream, which will swallow all white spaces from that stream.
Definition: streams.h:708
istream & operator>>(int &value)
Input and interpret next word from buffer as a signed integer value.
Definition: streams.h:562
istream & operator>>(char &value)
Input next character from buffer.
Definition: streams.h:543
istream & get(char *str, size_t n, char delim='\n')
Extract characters from this input stream and stores them as a C-string, until either (n - 1) charact...
Definition: streams.h:425
int peek()
Return the next character in this input stream, without extracting it.
Definition: streams.h:384
Input API based on a ring buffer.
Definition: streambuf.h:257
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 stream wrapper to provide formatted output API, a la C++.
Definition: streams.h:61
void write(const char *content, size_t size)
Write a block of data to this stream.
Definition: streams.h:116
void flush()
Flush this ostream and blocks until all its buffer has been written to the underlying device.
Definition: streams.h:89
ostream & operator<<(double value)
Output a floating point number, using the current minimum width() and precision().
Definition: streams.h:305
ostream & operator<<(const void *ptr)
Output the address of a pointer.
Definition: streams.h:160
ostream & operator<<(bool value)
Output a boolean value.
Definition: streams.h:175
ostream & operator<<(long value)
Output a signed long integral number, represented within the current base(), using the current minimu...
Definition: streams.h:271
void write(const flash::FlashStorage *str)
Write a flash-stored string (null-terminated) to this stream.
Definition: streams.h:144
ostream & operator<<(const flash::FlashStorage *str)
Output a C-string (\0 terminated) that is stored in flash memory.
Definition: streams.h:220
ostream & operator<<(char ch)
Output a single character.
Definition: streams.h:190
ostream & operator<<(MANIPULATOR func)
Apply a MANIPULATOR to this output stream.
Definition: streams.h:333
ostream & operator<<(unsigned int value)
Output an unsigned integral number, represented within the current base(), using the current minimum ...
Definition: streams.h:254
ostreambuf & rdbuf() const
Return the stream buffer associated with this stream.
Definition: streams.h:77
ostream & operator<<(const char *str)
Output a C-string (\0 terminated).
Definition: streams.h:205
void put(char c)
Insert character c into this stream.
Definition: streams.h:101
void write(const char *str)
Write a string (null-terminated) to this stream.
Definition: streams.h:130
ostream(ostreambuf &streambuf)
Construct a formatted output wrapper of streambuf.
Definition: streams.h:67
ostream & operator<<(unsigned long value)
Output an unsigned long integral number, represented within the current base(), using the current min...
Definition: streams.h:288
void(*)(ostream &) MANIPULATOR
General type of a manipulator function applicable to this output stream.
Definition: streams.h:315
ostream & operator<<(int value)
Output a signed integral number, represented within the current base(), using the current minimum wid...
Definition: streams.h:237
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 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
Flash memory utilities.
C++-like std::iostream facilities.
T peek(Queue< T, TREF > &queue)
Peek an item from the beginning of queue.
Definition: queue.h:573
T pull(Queue< T, TREF > &queue)
Pull an item from the beginning of queue.
Definition: queue.h:556
Defines C++-like streams API, based on circular buffers for input or output.
Definition: empty_streams.h:34
void flush(FSTREAM &stream)
Manipulator for an output stream, which will flush the stream buffer.
Definition: streams.h:716
void endl(FSTREAM &stream)
Manipulator for an output stream, which will insert a new-line character and flush the stream buffer.
Definition: streams.h:725
void ws(FSTREAM &stream)
Manipulator for an input stream, which will swallow all white spaces from that stream.
Definition: streams.h:708
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.
C++-like std::iostream facilities.
Simple time utilities.