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