1 /* 2 Print.cpp - Base class that provides print() and println() 3 Copyright (c) 2008 David A. Mellis. All right reserved. 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Modified 23 November 2006 by David A. Mellis 20 */ 21 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <string.h> 25 #include <math.h> 26 #include "wiring.h" 27 28 #include "Print.h" 29 30 // Public Methods ////////////////////////////////////////////////////////////// 31 32 /* default implementation: may be overridden */ 33 void Print::write(const char *str) 34 { 35 while (*str) 36 write(*str++); 37 } 38 39 /* default implementation: may be overridden */ 40 void Print::write(const uint8_t *buffer, size_t size) 41 { 42 while (size--) 43 write(*buffer++); 44 } 45 46 void Print::print(const String &s) 47 { 48 for (int i = 0; i < s.length(); i++) { 49 write(s[i]); 50 } 51 } 52 53 void Print::print(const char str[]) 54 { 55 write(str); 56 } 57 58 void Print::print(char c, int base) 59 { 60 print((long) c, base); 61 } 62 63 void Print::print(unsigned char b, int base) 64 { 65 print((unsigned long) b, base); 66 } 67 68 void Print::print(int n, int base) 69 { 70 print((long) n, base); 71 } 72 73 void Print::print(unsigned int n, int base) 74 { 75 print((unsigned long) n, base); 76 } 77 78 void Print::print(long n, int base) 79 { 80 if (base == 0) { 81 write(n); 82 } else if (base == 10) { 83 if (n < 0) { 84 print('-'); 85 n = -n; 86 } 87 printNumber(n, 10); 88 } else { 89 printNumber(n, base); 90 } 91 } 92 93 void Print::print(unsigned long n, int base) 94 { 95 if (base == 0) write(n); 96 else printNumber(n, base); 97 } 98 99 void Print::print(double n, int digits) 100 { 101 printFloat(n, digits); 102 } 103 104 void Print::println(void) 105 { 106 print('\r'); 107 print('\n'); 108 } 109 110 void Print::println(const String &s) 111 { 112 print(s); 113 println(); 114 } 115 116 void Print::println(const char c[]) 117 { 118 print(c); 119 println(); 120 } 121 122 void Print::println(char c, int base) 123 { 124 print(c, base); 125 println(); 126 } 127 128 void Print::println(unsigned char b, int base) 129 { 130 print(b, base); 131 println(); 132 } 133 134 void Print::println(int n, int base) 135 { 136 print(n, base); 137 println(); 138 } 139 140 void Print::println(unsigned int n, int base) 141 { 142 print(n, base); 143 println(); 144 } 145 146 void Print::println(long n, int base) 147 { 148 print(n, base); 149 println(); 150 } 151 152 void Print::println(unsigned long n, int base) 153 { 154 print(n, base); 155 println(); 156 } 157 158 void Print::println(double n, int digits) 159 { 160 print(n, digits); 161 println(); 162 } 163 164 // Private Methods ///////////////////////////////////////////////////////////// 165 166 void Print::printNumber(unsigned long n, uint8_t base) 167 { 168 unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. 169 unsigned long i = 0; 170 171 if (n == 0) { 172 print('0'); 173 return; 174 } 175 176 while (n > 0) { 177 buf[i++] = n % base; 178 n /= base; 179 } 180 181 for (; i > 0; i--) 182 print((char) (buf[i - 1] < 10 ? 183 '0' + buf[i - 1] : 184 'A' + buf[i - 1] - 10)); 185 } 186 187 void Print::printFloat(double number, uint8_t digits) 188 { 189 // Handle negative numbers 190 if (number < 0.0) 191 { 192 print('-'); 193 number = -number; 194 } 195 196 // Round correctly so that print(1.999, 2) prints as "2.00" 197 double rounding = 0.5; 198 for (uint8_t i=0; i<digits; ++i) 199 rounding /= 10.0; 200 201 number += rounding; 202 203 // Extract the integer part of the number and print it 204 unsigned long int_part = (unsigned long)number; 205 double remainder = number - (double)int_part; 206 print(int_part); 207 208 // Print the decimal point, but only if there are digits beyond 209 if (digits > 0) 210 print("."); 211 212 // Extract digits from the remainder one at a time 213 while (digits-- > 0) 214 { 215 remainder *= 10.0; 216 int toPrint = int(remainder); 217 print(toPrint); 218 remainder -= toPrint; 219 } 220 } 221