COSA
An Object-Oriented Platform for Arduino Programming
IOStream.cpp
Go to the documentation of this file.
1 
21 #include "Cosa/IOStream.hh"
22 #include "Cosa/Power.hh"
23 #include <ctype.h>
24 
25 const char IOStream::CR[] __PROGMEM = "\n";
26 const char IOStream::LF[] __PROGMEM = "\r";
27 const char IOStream::CRLF[] __PROGMEM = "\r\n";
28 
30  m_dev(dev),
31  m_base(dec),
32  m_width(6),
33  m_prec(4),
34  m_eols((str_P) CRLF)
35 {}
36 
38  m_dev(NULL),
39  m_base(dec),
40  m_width(6),
41  m_prec(4),
42  m_eols((str_P) CRLF)
43 {}
44 
45 void
46 IOStream::print(int n, Base base)
47 {
48  if (base != bcd) {
49  char buf[BUF_MAX];
50  if (base == dec) {
51  print(itoa(n, buf, base));
52  }
53  else {
54  print_prefix(base);
55  print(utoa(n, buf, base));
56  }
57  }
58  else {
59  print((char) ('0' + ((n >> 4) & 0xf)));
60  print((char) ('0' + (n & 0xf)));
61  }
62 }
63 
64 void
65 IOStream::print(long int n, Base base)
66 {
67  if (UNLIKELY(base != dec)) print_prefix(base);
68  char buf[BUF_MAX];
69  print(ltoa(n, buf, base));
70 }
71 
72 void
73 IOStream::print(unsigned int n, Base base)
74 {
75  if (UNLIKELY(base != dec)) print_prefix(base);
76  char buf[BUF_MAX];
77  print(utoa(n, buf, base));
78 }
79 
80 void
81 IOStream::print(unsigned long int n, Base base)
82 {
83  if (UNLIKELY(base != dec)) print_prefix(base);
84  char buf[BUF_MAX];
85  print(ultoa(n, buf, base));
86 }
87 
88 void
89 IOStream::print(unsigned int n, uint8_t digits, Base base)
90 {
91  char buf[BUF_MAX];
92  utoa(n, buf, base);
93  for (uint8_t length = strlen(buf); length < digits; length++)
94  print('0');
95  print(buf);
96 }
97 
98 void
99 IOStream::print(unsigned long int n, uint8_t digits, Base base)
100 {
101  char buf[BUF_MAX];
102  ultoa(n, buf, base);
103  for (uint8_t length = strlen(buf); length < digits; length++)
104  print('0');
105  print(buf);
106 }
107 
108 void
109 IOStream::print(double value, int8_t width, uint8_t prec)
110 {
111  char buf[BUF_MAX];
112  dtostrf(value, width, prec, buf);
113  print(buf);
114 }
115 
116 void
118 {
119  int c;
120  while ((c = buffer->getchar()) != EOF)
121  print((char) c);
122 }
123 
124 void
126 {
127  if (base == hex)
128  print(PSTR("0x"));
129  else if (base == bin)
130  print(PSTR("0b"));
131  else if (base == oct)
132  print(PSTR("0"));
133 }
134 
135 void
136 IOStream::print(uint32_t src, const void *ptr, size_t size, Base base, uint8_t max)
137 {
138  Base b = (base != dec ? hex : dec);
139  uint8_t w = (base == hex ? 2 : (base == bin ? 8 : 3));
140  uint8_t* p = (uint8_t*) ptr;
141  uint8_t n = 0;
142  print(src, 6, b);
143  print(PSTR(": "));
144  while (size--) {
145  print((unsigned int) *p++, w, base);
146  src += 1;
147  if (++n < max) {
148  print(PSTR(" "));
149  }
150  else {
151  println();
152  n = 0;
153  if (size > 0) {
154  print(src, 6, b);
155  print(PSTR(": "));
156  }
157  }
158  }
159  if (n != 0) println();
160 }
161 
162 void
163 IOStream::vprintf(str_P format, va_list args)
164 {
165  const char* s = (const char*) format;
166  uint8_t is_signed;
167  Base base;
168  char c;
169  while ((c = pgm_read_byte(s++)) != 0) {
170  if (c == '%') {
171  is_signed = 1;
172  base = dec;
173  next:
174  c = pgm_read_byte(s++);
175  if (c == 0) s--;
176  switch (c) {
177  case 'b':
178  base = bin;
179  goto next;
180  case 'B':
181  base = bcd;
182  goto next;
183  case 'o':
184  base = oct;
185  goto next;
186  case 'h':
187  case 'x':
188  base = hex;
189  goto next;
190  case 'u':
191  is_signed = 0;
192  goto next;
193  case 'c':
194  print((char) va_arg(args, int));
195  continue;
196  case 'p':
197  print(va_arg(args, void*));
198  continue;
199  case 's':
200  print(va_arg(args, char*));
201  continue;
202  case 'S':
203  print(va_arg(args, str_P));
204  continue;
205  case 'd':
206  if (is_signed)
207  print(va_arg(args, int), base);
208  else
209  print(va_arg(args, unsigned int), base);
210  continue;
211  case 'l':
212  if (is_signed)
213  print(va_arg(args, long int), base);
214  else
215  print(va_arg(args, unsigned long int), base);
216  continue;
217  };
218  }
219  print(c);
220  }
221 }
222 
223 char*
224 IOStream::scan(char *s, size_t count)
225 {
226  if (UNLIKELY(m_dev == NULL)) return (NULL);
227  char* res = s;
228 
229  // Skip whitespace
230  int c = m_dev->peekchar();
231  while (c <= ' ' && c != '\n') {
232  if (UNLIKELY(c == EOF)) return (NULL);
233  c = m_dev->getchar();
234  c = m_dev->peekchar();
235  }
236  c = m_dev->getchar();
237 
238  // Scan the token; identifier, number or special character
239  count -= 1;
240  *s++ = c;
241  if (isalpha(c)) {
242  while (count--) {
243  c = m_dev->peekchar();
244  if (!isalnum(c)) break;
245  c = m_dev->getchar();
246  *s++ = c;
247  }
248  }
249  else if (isdigit(c) || c == '-') {
250  while (count--) {
251  c = m_dev->peekchar();
252  if (!isdigit(c)) break;
253  c = m_dev->getchar();
254  *s++ = c;
255  }
256  }
257  *s = 0;
258  return (res);
259 }
260 
261 char*
262 IOStream::readline(char* buf, size_t size, bool echo)
263 {
264  const char DEL = 127;
265  const char ESC = 27;
266  if (UNLIKELY(m_dev == NULL)) return (NULL);
267  int count = m_dev->available();
268  if (UNLIKELY(count <= 0)) return (NULL);
269  size_t len = strlen(buf);
270  char* s = buf + len;
271  char c = 0;
272  while (count--) {
273  c = m_dev->getchar();
274  if (c == ESC) continue;
275  if (c == '\b' || c == DEL) {
276  if (len > 0) {
277  if (echo) print(PSTR("\b \b"));
278  len -= 1;
279  s -= 1;
280  }
281  }
282  else {
283  if (c == '\r') {
284  if (echo) print(c);
285  if (m_dev->eol() == CRLF_MODE) continue;
286  c = '\n';
287  }
288  if (echo) print(c);
289  if (len < size) {
290  len += 1;
291  *s++ = c;
292  }
293  if (c == '\n') break;
294  }
295  }
296  *s = 0;
297  return (c == '\n' ? buf : NULL);
298 }
299 
char * scan(char *s, size_t count)
Definition: IOStream.cpp:224
const char IOStream::CR[] __PROGMEM
Definition: IOStream.cpp:25
IOStream & dec(IOStream &outs)
Definition: IOStream.hh:781
void println()
Definition: IOStream.hh:467
void print(int value, Base base=dec)
Definition: IOStream.cpp:46
int8_t m_width
Minimum width of output string.
Definition: IOStream.hh:725
#define NULL
Definition: Types.h:101
static const char CR[]
Definition: IOStream.hh:36
#define PSTR(s)
Definition: Types.h:202
void eol(Mode mode)
Definition: IOStream.hh:103
IOStream()
Definition: IOStream.cpp:37
static char * ltoa(long __val, char *__s, int base)
int8_t width(int8_t value)
Definition: IOStream.hh:315
void print_prefix(Base base)
Definition: IOStream.cpp:125
char * readline(char *buf, size_t size, bool echo=true)
Definition: IOStream.cpp:262
const class prog_str * str_P
Definition: Types.h:187
static const char CRLF[]
Definition: IOStream.hh:38
static char * itoa(int __val, char *__s, int base)
static char * utoa(unsigned int __val, char *__s, int base)
Base m_base
Base for next output operator.
Definition: IOStream.hh:724
static const int EOF
Definition: IOStream.hh:33
virtual int available()
virtual int getchar()
virtual int peekchar()
Device * m_dev
Delegated device.
Definition: IOStream.hh:723
#define UNLIKELY(x)
Definition: Types.h:153
static const size_t BUF_MAX
Definition: IOStream.hh:730
static const char LF[]
Definition: IOStream.hh:37
void vprintf(str_P format, va_list args)
Definition: IOStream.cpp:163
str_P m_eols
End of line string (program memory).
Definition: IOStream.hh:727
uint8_t m_prec
Number of digits after decimal sign.
Definition: IOStream.hh:726
static char * ultoa(unsigned long __val, char *__s, int base)