COSA
An Object-Oriented Platform for Arduino Programming
IOStream_dtoa.cpp
Go to the documentation of this file.
1 
16 #include "Cosa/IOStream.hh"
17 
18 #if !defined(COSA_IOSTREAM_STDLIB_DTOA)
19 #include <avr/pgmspace.h>
20 
21 static const unsigned long digits8[] __PROGMEM = {
22  1073741824,
23  134217728,
24  16777216,
25  2097152,
26  262144,
27  32768,
28  4096,
29  512,
30  64,
31  8,
32  1,
33 };
34 
35 static const unsigned long digits10[] __PROGMEM = {
36  1000000000,
37  100000000,
38  10000000,
39  1000000,
40  100000,
41  10000,
42  1000,
43  100,
44  10,
45  1,
46 };
47 
48 static const char letters[] __PROGMEM = "0123456789abcdef";
49 
50 char*
51 IOStream::ultoa(unsigned long __val, char *__s, int base)
52 {
53  unsigned char i, j, k, l, first;
54  const uint8_t* p;
55  first = 1;
56  j = 0;
57 
58  if (__val != 0UL) {
59  if (base == 2) {
60  // Optimize for base(2)
61  first = 0;
62  p = ((uint8_t*) &__val) + sizeof(__val) - 1;
63  for (i = 0; i < 4 && *p == 0; i++, p--)
64  ;
65  k = *p--;
66  for (l = 0; l < 8; l++) {
67  if (k & 0x80) break;
68  k <<= 1;
69  }
70  for (; i < 4; i++, l = 0, k = *p--) {
71  for (; l < 8; l++) {
72  __s[j++] = (k & 0x80) ? '1' : '0';
73  k <<= 1;
74  }
75  }
76  }
77  else if (base == 16) {
78  // Optimize for base(16)
79  first = 0;
80  p = ((uint8_t*) &__val) + sizeof(__val) - 1;
81  for (i = 0; i < 4 && *p == 0; i++, p--)
82  ;
83  k = *p--;
84  if (k & 0xf0) __s[j++] = pgm_read_byte(letters + (k >> 4));
85  __s[j++] = pgm_read_byte(letters + (k & 0xf));
86  for (i++; i < 4; i++) {
87  k = *p--;
88  __s[j++] = pgm_read_byte(letters + (k >> 4));
89  __s[j++] = pgm_read_byte(letters + (k & 0xf));
90  }
91  }
92  else {
93  const unsigned long *d;
94  unsigned char max;
95  if (base == 8) {
96  max = sizeof(digits8) / sizeof(unsigned long);
97  d = digits8;
98  }
99  else {
100  max = sizeof(digits10) / sizeof(unsigned long);
101  d = digits10;
102  }
103  for (i = 0; i < max; i++) {
104  unsigned long check = pgm_read_dword(d + i);
105  if (check > __val) {
106  if (first)
107  continue;
108  __s[j++] = '0';
109  continue;
110  }
111  first = k = 0;
112  while(check <= __val) {
113  __val -= check;
114  k++;
115  }
116  __s[j++] = pgm_read_byte(letters + k);
117  }
118  }
119  }
120 
121  if (first)
122  __s[j++] = '0';
123  __s[j] = 0;
124 
125  return (__s);
126 }
127 
128 char*
129 IOStream::ltoa(long __val, char *__s, int base)
130 {
131  if (__val >= 0 || base != 10)
132  return (ultoa((unsigned long)__val, __s, base));
133  __s[0] = '-';
134  return (ultoa((unsigned long)(-__val), __s + 1, base) - 1);
135 }
136 
137 char*
138 IOStream::utoa(unsigned int __val, char *__s, int base)
139 {
140  return (ultoa(((unsigned long) __val) & 0xffff, __s, base));
141 }
142 
143 char*
144 IOStream::itoa(int __val, char *__s, int base)
145 {
146  return (ltoa((long)__val, __s, base));
147 }
148 
149 #endif
static char * ltoa(long __val, char *__s, int base)
static const unsigned long digits8[] __PROGMEM
static char * itoa(int __val, char *__s, int base)
static char * utoa(unsigned int __val, char *__s, int base)
static char * ultoa(unsigned long __val, char *__s, int base)