Print.h
Go to the documentation of this file.
1 /* $Id: Print.h 1156 2011-06-07 04:01:16Z bhagman $
2 ||
3 || @author Hernando Barragan <b@wiring.org.co>
4 || @url http://wiring.org.co/
5 || @contribution Nicholas Zambetti
6 || @contribution Brett Hagman <bhagman@wiring.org.co>
7 || @contribution Alexander Brevig <abrevig@wiring.org.co>
8 ||
9 || @description
10 || | Print library.
11 || |
12 || | Wiring Common API
13 || #
14 ||
15 || @license Please see cores/Common/License.txt.
16 ||
17 */
18 
19 #pragma once
20 
21 #ifdef __cplusplus
22 
23 #include "Printable.h"
24 #include "WString.h"
25 
26 #define INITIAL_PRINTF_BUFFSIZE 128
27 
36 class Print
37 {
38 public:
39  virtual ~Print()
40  {
41  }
42 
47  {
48  return write_error;
49  }
50 
54  {
55  setWriteError(0);
56  }
57 
62  virtual size_t write(uint8_t c) = 0;
63 
68  size_t write(const char* str)
69  {
70  if(str == nullptr) {
71  return 0;
72  }
73  return write(reinterpret_cast<const uint8_t*>(str), strlen(str));
74  }
75 
81  virtual size_t write(const uint8_t* buffer, size_t size);
82 
88  size_t write(const char* buffer, size_t size)
89  {
90  return write((const uint8_t*)buffer, size);
91  }
92 
97  size_t print(char c)
98  {
99  return write(c);
100  }
101 
106  size_t print(const char str[])
107  {
108  return write(str);
109  }
110 
118  size_t print(unsigned long num, uint8_t base = DEC)
119  {
120  if(base == 0) {
121  return write(num);
122  } else {
123  return printNumber(num, base);
124  }
125  }
126 
127  template <typename... Args> size_t print(unsigned long num, Args... args)
128  {
129  return printNumber(num, args...);
130  }
131 
132  template <typename... Args> size_t print(const unsigned long long& num, Args... args)
133  {
134  return printNumber(num, args...);
135  }
136 
137  size_t print(long num, uint8_t base = DEC)
138  {
139  if(base == 0) {
140  return write(num);
141  } else {
142  return printNumber(num, base);
143  }
144  }
145 
146  template <typename... Args> size_t print(long num, Args... args)
147  {
148  return printNumber(num, args...);
149  }
150 
151  template <typename... Args> size_t print(const long long& num, Args... args)
152  {
153  return printNumber(num, args...);
154  }
155 
156  template <typename... Args> size_t print(unsigned int num, Args... args)
157  {
158  return print((unsigned long)num, args...);
159  }
160 
161  template <typename... Args> size_t print(unsigned char num, Args... args)
162  {
163  return print((unsigned long)num, args...);
164  }
165 
166  template <typename... Args> size_t print(int num, Args... args)
167  {
168  return printNumber((long)num, args...);
169  }
177  size_t print(double num, int digits = 2)
178  {
179  return printFloat(num, digits);
180  }
181 
182  /*
183  * Helper class using SFINAE to identify *any* class with a `printTo` method, even if not a base of `Printable`.
184  *
185  * https://stackoverflow.com/a/257382
186  */
187  template <typename T> class has_printTo
188  {
189  template <typename C> static uint8_t test(decltype(&C::printTo));
190  template <typename C> static uint32_t test(...);
191 
192  public:
193  enum { value = (sizeof(test<T>(0)) == 1) };
194  };
195 
200  template <typename T> typename std::enable_if<has_printTo<T>::value, size_t>::type print(const T& obj)
201  {
202  return obj.printTo(*this);
203  }
204 
209  size_t print(const String& s)
210  {
211  return write(s.c_str(), s.length());
212  }
213 
217  template <typename E>
218  typename std::enable_if<std::is_enum<E>::value && !std::is_convertible<E, int>::value, size_t>::type print(E value)
219  {
220  extern String toString(E e);
221  return print(toString(value));
222  }
223 
227  size_t println()
228  {
229  return write("\r\n", 2);
230  }
231 
235  template <typename... Args> size_t println(const Args&... args)
236  {
237  return print(args...) + println();
238  }
239 
246  size_t printf(const char* fmt, ...) __attribute__((format(printf, 2, 3)));
247 
248 private:
249  int write_error = 0;
250  size_t printNumber(unsigned long num, uint8_t base = DEC, uint8_t width = 0, char pad = '0');
251  size_t printNumber(const unsigned long long& num, uint8_t base = DEC, uint8_t width = 0, char pad = '0');
252  size_t printNumber(long num, uint8_t base = DEC, uint8_t width = 0, char pad = '0');
253  size_t printNumber(const long long& num, uint8_t base = DEC, uint8_t width = 0, char pad = '0');
254  size_t printFloat(double num, uint8_t digits);
255 
256 protected:
257  void setWriteError(int err = 1)
258  {
259  write_error = err;
260  }
261 };
262 
263 inline Print& operator<<(Print& p, const char value[])
264 {
265  p.print(value);
266  return p;
267 }
268 
269 template <typename T>
270 typename std::enable_if<!std::is_array<T>::value, Print&>::type operator<<(Print& p, const T& value)
271 {
272  p.print(value);
273  return p;
274 }
275 
276 // Thanks to Arduino forum user Paul V. who suggested this
277 // clever technique to allow for expressions like
278 // Serial << "Hello!" << endl;
279 enum EndLineCode { endl };
280 
282 {
283  p.println();
284  return p;
285 }
286 
289 #endif // __cplusplus
std::enable_if< std::is_integral< T >::value, String >::type toString(T value)
Definition: BitSet.h:481
#define DEC
Definition: WConstants.h:67
Definition: Print.h:188
@ value
Definition: Print.h:193
Provides formatted output to stream.
Definition: Print.h:37
std::enable_if< std::is_enum< E >::value &&!std::is_convertible< E, int >::value, size_t >::type print(E value)
enums can be printed as strings provided they have a toString(E) implementation.
Definition: Print.h:218
size_t print(double num, int digits=2)
Print a floating-point number to output stream.
Definition: Print.h:177
size_t print(long num, Args... args)
Definition: Print.h:146
size_t print(const String &s)
Prints a String to output stream.
Definition: Print.h:209
size_t print(unsigned long num, Args... args)
Definition: Print.h:127
size_t print(long num, uint8_t base=DEC)
Definition: Print.h:137
void setWriteError(int err=1)
Definition: Print.h:257
std::enable_if< has_printTo< T >::value, size_t >::type print(const T &obj)
Prints a Printable object to output stream.
Definition: Print.h:200
size_t print(const char str[])
Prints a c-string to output stream.
Definition: Print.h:106
size_t print(unsigned int num, Args... args)
Definition: Print.h:156
size_t write(const char *str)
Writes a c-string to output stream.
Definition: Print.h:68
size_t print(unsigned long num, uint8_t base=DEC)
Definition: Print.h:118
size_t printf(const char *fmt,...)
Prints a formatted c-string to output stream.
size_t print(const long long &num, Args... args)
Definition: Print.h:151
size_t print(int num, Args... args)
Definition: Print.h:166
virtual size_t write(const uint8_t *buffer, size_t size)
Writes characters from a buffer to output stream.
int getWriteError()
Gets last error.
Definition: Print.h:46
size_t println()
Prints a newline to output stream.
Definition: Print.h:227
virtual size_t write(uint8_t c)=0
Writes a single character to output stream.
size_t print(unsigned char num, Args... args)
Definition: Print.h:161
virtual ~Print()
Definition: Print.h:39
size_t write(const char *buffer, size_t size)
Writes characters from a buffer to output stream.
Definition: Print.h:88
size_t print(const unsigned long long &num, Args... args)
Definition: Print.h:132
void clearWriteError()
Clears the last write error.
Definition: Print.h:53
size_t print(char c)
Prints a single character to output stream.
Definition: Print.h:97
size_t println(const Args &... args)
Print value plus newline to output stream.
Definition: Print.h:235
The String class.
Definition: WString.h:137
const char * c_str() const
Get a constant (un-modifiable) pointer to String content.
Definition: WString.h:616
size_t length(void) const
Obtain the String length in characters, excluding NUL terminator.
Definition: WString.h:243
EndLineCode
Definition: Print.h:279
Print & operator<<(Print &p, const char value[])
Definition: Print.h:263
@ endl
Definition: Print.h:279
Definition: testrunner.h:74
#define str(s)
Definition: testrunner.h:124