Control Surface new-input
MIDI Control Surface 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)
9 #define FLUSH
10 #endif
11 
13 
14 /* #define OCT 8 */
15 
16 uint8_t formatPrintStream = DEC;
17 bool boolalphaPrintStream = false;
21 enum : char { LOWERCASE = 0x7F, UPPERCASE = 0x5F } casePrintStream = LOWERCASE;
22 bool showbasePrintStream = false;
23 
24 template <class T>
25 Print &printIntegral(Print &printer, T i);
26 
27 Print &endl(Print &printer) {
28  printer.println();
29 #ifdef FLUSH
30  printer.flush();
31 #endif
32  return printer;
33 }
34 
35 Print &uppercase(Print &printer) {
37  return printer;
38 }
39 
40 Print &nouppercase(Print &printer) {
42  return printer;
43 }
44 
45 Print &showbase(Print &printer) {
46  showbasePrintStream = true;
47  return printer;
48 }
49 
50 Print &noshowbase(Print &printer) {
51  showbasePrintStream = false;
52  return printer;
53 }
54 
55 Print &flush(Print &printer) {
56 #ifdef FLUSH
57  printer.flush();
58 #endif
59  return printer;
60 }
61 
62 Print &hex(Print &printer) {
63  formatPrintStream = HEX;
64  return printer;
65 }
66 
67 /* Print &oct(Print &printer) {
68  formatPrintStream = OCT;
69  return printer;
70 } */
71 
72 Print &bin(Print &printer) {
73  formatPrintStream = BIN;
74  return printer;
75 }
76 
77 Print &dec(Print &printer) {
78  formatPrintStream = DEC;
79  return printer;
80 }
81 
82 Print &boolalpha(Print &printer) {
83  boolalphaPrintStream = true;
84  return printer;
85 }
86 Print &noboolalpha(Print &printer) {
87  boolalphaPrintStream = false;
88  return printer;
89 }
90 
91 Print &leadingzeros(Print &printer) {
93  return printer;
94 }
95 Print &noleadingzeros(Print &printer) {
97  return printer;
98 }
99 Print &operator<<(Print &printer, const __FlashStringHelper *s) {
100  printer.print(s);
101  return printer;
102 }
103 #ifdef ARDUINO
104 Print &operator<<(Print &printer, const String &s) {
105  printer.print(s);
106  return printer;
107 }
108 #endif
109 Print &operator<<(Print &printer, const char s[]) {
110  printer.print(s);
111  return printer;
112 }
113 Print &operator<<(Print &printer, char c) {
114  printer.print(c);
115  return printer;
116 }
117 Print &operator<<(Print &printer, unsigned char i) {
118  return printIntegral(printer, i);
119 }
120 Print &operator<<(Print &printer, int i) { return printIntegral(printer, i); }
121 Print &operator<<(Print &printer, unsigned int i) {
122  return printIntegral(printer, i);
123 }
124 Print &operator<<(Print &printer, int8_t i) {
125  return printIntegral(printer, i);
126 }
127 Print &operator<<(Print &printer, long i) { return printIntegral(printer, i); }
128 Print &operator<<(Print &printer, unsigned long i) {
129  return printIntegral(printer, i);
130 }
131 Print &operator<<(Print &printer, double d) {
132  printer.print(d, precisionPrintStream);
133  return printer;
134 }
135 Print &operator<<(Print &printer, float f) {
136  return printer << static_cast<double>(f);
137 }
138 Print &operator<<(Print &printer, const Printable &p) {
139  printer.print(p);
140  return printer;
141 }
142 Print &operator<<(Print &printer, bool b) {
144  printer.print(b ? F("true") : F("false"));
145  else
146  printer.print(b);
147  return printer;
148 }
149 
150 Print &operator<<(Print &printer, manipulator pf) { return pf(printer); }
151 
152 Setbase setbase(uint8_t base) { return {base}; }
153 Print &operator<<(Print &printer, Setbase f) {
155  return printer;
156 }
157 
158 Setbytesep setbytesep(char bytesep) { return {bytesep}; }
159 Print &operator<<(Print &printer, Setbytesep f) {
161  return printer;
162 }
163 
164 Setprecision setprecision(int n) { return {n}; }
165 Print &operator<<(Print &printer, Setprecision f) {
167  return printer;
168 }
169 
170 static 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 
180 template <class T>
181 void 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));
192  if (byteSeparatorPrintStream && i)
193  printer.print(byteSeparatorPrintStream);
194  }
195  }
196 }
197 
198 template <class T>
199 void 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>
220 void printOct(Print &printer, T val)
221 {
222  ; // TODO
223 } */
224 
225 template <class T>
226 Print &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 
239 Print &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 
256 std::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
uint8_t M_base
Definition: PrintStream.hpp:58
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 & 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 & manipulator(Print &)
Definition: PrintStream.hpp:21
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:28
Print & printIntegral(Print &printer, T i)
static char nibble_to_hex(uint8_t nibble)
void printBin(Print &printer, T val)
char byteSeparatorPrintStream
Definition: PrintStream.cpp:20
@ UPPERCASE
Definition: PrintStream.cpp:21
@ LOWERCASE
Definition: PrintStream.cpp:21
uint8_t formatPrintStream
Definition: PrintStream.cpp:16
bool boolalphaPrintStream
Definition: PrintStream.cpp:17
bool leadingZerosPrintStream
Definition: PrintStream.cpp:18
void printHex(Print &printer, T val)
uint8_t precisionPrintStream
Definition: PrintStream.cpp:19
bool showbasePrintStream
Definition: PrintStream.cpp:22
enum AH::@2 casePrintStream
const uint8_t * data
Definition: PrintStream.hpp:78
size_t length
Definition: PrintStream.hpp:79