Arduino Helpers master
Utility library for Arduino
PrintStream.cpp
Go to the documentation of this file.
1// https://github.com/tttapa/Arduino-PrintStream/blob/6a9e0d365be0b3d84187daa2a8a7bda8d541472e/src/PrintStream.cpp
2
3#include "PrintStream.hpp"
4
5// LCOV_EXCL_START
6
7#if not defined(ARDUINO_ARCH_ESP32) && not defined(ARDUINO_ARCH_SAM) && \
8 not defined(ARDUINO_API_VERSION) && not defined(ArduinoFake)
9#define FLUSH
10#endif
11
13
14/* #define OCT 8 */
15
16uint8_t formatPrintStream = DEC;
21enum : char { LOWERCASE = 0x7F, UPPERCASE = 0x5F } casePrintStream = LOWERCASE;
23
24template <class T>
25Print &printIntegral(Print &printer, T i);
26
27Print &endl(Print &printer) {
28 printer.println();
29#ifdef FLUSH
30 printer.flush();
31#endif
32 return printer;
33}
34
35Print &uppercase(Print &printer) {
37 return printer;
38}
39
40Print &nouppercase(Print &printer) {
42 return printer;
43}
44
45Print &showbase(Print &printer) {
47 return printer;
48}
49
50Print &noshowbase(Print &printer) {
51 showbasePrintStream = false;
52 return printer;
53}
54
55Print &flush(Print &printer) {
56#ifdef FLUSH
57 printer.flush();
58#endif
59 return printer;
60}
61
62Print &hex(Print &printer) {
64 return printer;
65}
66
67/* Print &oct(Print &printer) {
68 formatPrintStream = OCT;
69 return printer;
70} */
71
72Print &bin(Print &printer) {
74 return printer;
75}
76
77Print &dec(Print &printer) {
79 return printer;
80}
81
82Print &boolalpha(Print &printer) {
84 return printer;
85}
86Print &noboolalpha(Print &printer) {
88 return printer;
89}
90
91Print &leadingzeros(Print &printer) {
93 return printer;
94}
95Print &noleadingzeros(Print &printer) {
97 return printer;
98}
99Print &operator<<(Print &printer, const __FlashStringHelper *s) {
100 printer.print(s);
101 return printer;
102}
103#ifdef ARDUINO
104Print &operator<<(Print &printer, const String &s) {
105 printer.print(s);
106 return printer;
107}
108#endif
109Print &operator<<(Print &printer, const char s[]) {
110 printer.print(s);
111 return printer;
112}
113Print &operator<<(Print &printer, char c) {
114 printer.print(c);
115 return printer;
116}
117Print &operator<<(Print &printer, unsigned char i) {
118 return printIntegral(printer, i);
119}
120Print &operator<<(Print &printer, int i) { return printIntegral(printer, i); }
121Print &operator<<(Print &printer, unsigned int i) {
122 return printIntegral(printer, i);
123}
124Print &operator<<(Print &printer, int8_t i) {
125 return printIntegral(printer, i);
126}
127Print &operator<<(Print &printer, long i) { return printIntegral(printer, i); }
128Print &operator<<(Print &printer, unsigned long i) {
129 return printIntegral(printer, i);
130}
131Print &operator<<(Print &printer, double d) {
132 printer.print(d, precisionPrintStream);
133 return printer;
134}
135Print &operator<<(Print &printer, float f) {
136 return printer << static_cast<double>(f);
137}
138Print &operator<<(Print &printer, const Printable &p) {
139 printer.print(p);
140 return printer;
141}
142Print &operator<<(Print &printer, bool b) {
144 printer.print(b ? F("true") : F("false"));
145 else
146 printer.print(b);
147 return printer;
148}
149
150Print &operator<<(Print &printer, manipulator pf) { return pf(printer); }
151
152Setbase setbase(uint8_t base) { return {base}; }
153Print &operator<<(Print &printer, Setbase f) {
155 return printer;
156}
157
158Setbytesep setbytesep(char bytesep) { return {bytesep}; }
159Print &operator<<(Print &printer, Setbytesep f) {
161 return printer;
162}
163
164Setprecision setprecision(int n) { return {n}; }
165Print &operator<<(Print &printer, Setprecision f) {
167 return printer;
168}
169
170static char nibble_to_hex(
171 uint8_t nibble) { // convert a 4-bit nibble to a hexadecimal character
172 nibble &= 0xF;
173 return nibble > 9 ? nibble - 10 + ('a' & casePrintStream) : nibble + '0';
174}
175
176#if __BYTE_ORDER != __LITTLE_ENDIAN
177#error "Byte order not supported"
178#endif
179
180template <class T>
181void printHex(Print &printer, T val) {
183 printer.print("0x");
184 bool nonZero = false;
185 for (int i = sizeof(val) - 1; i >= 0; i--) {
186 uint8_t currByte = ((uint8_t *)&val)[i];
187 if (currByte != 0 || i == 0)
188 nonZero = true;
189 if (leadingZerosPrintStream || nonZero) {
190 printer.print(nibble_to_hex(currByte >> 4));
191 printer.print(nibble_to_hex(currByte));
193 printer.print(byteSeparatorPrintStream);
194 }
195 }
196}
197
198template <class T>
199void printBin(Print &printer, T val) {
201 printer.print("0b");
202 bool nonZero = false;
203 for (int i = sizeof(val) - 1; i >= 0; i--) {
204 uint8_t currByte = ((uint8_t *)&val)[i];
205 for (int j = 7; j >= 0; j--) {
206 uint8_t currBit = currByte & 0x80;
207 if (currBit != 0 || (i == 0 && j == 0))
208 nonZero = true;
209 if (leadingZerosPrintStream || nonZero)
210 printer.print(currBit ? '1' : '0');
211 currByte <<= 1;
212 }
213 if (byteSeparatorPrintStream && i &&
214 (leadingZerosPrintStream || nonZero))
215 printer.print(byteSeparatorPrintStream);
216 }
217}
218
219/* template <class T>
220void printOct(Print &printer, T val)
221{
222 ; // TODO
223} */
224
225template <class T>
226Print &printIntegral(Print &printer, T i) {
227 switch (formatPrintStream) {
228 case DEC: printer.print(i); break;
229 case HEX: printHex(printer, i); break;
230 case BIN: printBin(printer, i); break;
231 /* case OCT:
232 printOct(printer, i);
233 break; */
234 default: break;
235 }
236 return printer;
237}
238
239Print &operator<<(Print &p, HexDump h) {
240 if (h.length == 0)
241 return p;
242
243 auto temp_case = casePrintStream;
245 while (h.length-- > 1) {
246 printHex(p, *h.data++);
247 p.print(' ');
248 }
249 printHex(p, *h.data++);
250 casePrintStream = temp_case;
251 return p;
252}
253
254#ifndef ARDUINO
255
256std::ostream &operator<<(std::ostream &p, HexDump h) {
257 if (h.length == 0)
258 return p;
259
260 auto hex_nibble_to_char = [](uint8_t nibble) -> char {
261 nibble &= 0xF;
262 return nibble > 9 ? nibble - 10 + 'A' : nibble + '0';
263 };
264 auto printHex = [&](std::ostream &p, uint8_t b) {
265 p << hex_nibble_to_char(b >> 4) << hex_nibble_to_char(b);
266 };
267
268 while (h.length-- > 1) {
269 printHex(p, *h.data++);
270 p << ' ';
271 }
272 printHex(p, *h.data++);
273 return p;
274}
275
276#endif
277
279
280// LCOV_EXCL_STOP
#define END_AH_NAMESPACE
#define BEGIN_AH_NAMESPACE
enum @2 casePrintStream
Print & printIntegral(Print &printer, T i)
char byteSeparatorPrintStream
Definition: PrintStream.cpp:20
@ UPPERCASE
Definition: PrintStream.cpp:21
@ LOWERCASE
Definition: PrintStream.cpp:21
static char nibble_to_hex(uint8_t nibble)
void printBin(Print &printer, T val)
uint8_t formatPrintStream
Definition: PrintStream.cpp:16
bool boolalphaPrintStream
Definition: PrintStream.cpp:17
bool leadingZerosPrintStream
Definition: PrintStream.cpp:18
uint8_t precisionPrintStream
Definition: PrintStream.cpp:19
void printHex(Print &printer, T val)
bool showbasePrintStream
Definition: PrintStream.cpp:22
Print & hex(Print &printer)
Definition: PrintStream.cpp:62
Print & bin(Print &printer)
Definition: PrintStream.cpp:72
Print & nouppercase(Print &printer)
Definition: PrintStream.cpp:40
Print & endl(Print &printer)
Definition: PrintStream.cpp:27
Print & uppercase(Print &printer)
Definition: PrintStream.cpp:35
Print & flush(Print &printer)
Definition: PrintStream.cpp:55
Print & showbase(Print &printer)
Definition: PrintStream.cpp:45
Print & manipulator(Print &)
Definition: PrintStream.hpp:16
Print & boolalpha(Print &printer)
Definition: PrintStream.cpp:82
Setbytesep setbytesep(char bytesep)
Print & leadingzeros(Print &printer)
Definition: PrintStream.cpp:91
Print & noshowbase(Print &printer)
Definition: PrintStream.cpp:50
Print & dec(Print &printer)
Definition: PrintStream.cpp:77
Print & noboolalpha(Print &printer)
Definition: PrintStream.cpp:86
Print & noleadingzeros(Print &printer)
Definition: PrintStream.cpp:95
Setbase setbase(uint8_t base)
Setprecision setprecision(int n)
Print & operator<<(Print &os, Quaternion e)
Printing.
Definition: Quaternion.cpp:26
const uint8_t * data
Definition: PrintStream.hpp:74
size_t length
Definition: PrintStream.hpp:75
uint8_t M_base
Definition: PrintStream.hpp:53
char M_bytesep
Definition: PrintStream.hpp:65