What change would like to see?
The Print class could make use if its own block write method.
Why?
Some classes that use Print, such as Ethernet, can substantially benefit
from the block write.
Would this cause any incompatibilities with previous versions? If so, how
can these be mitigated?
If another class does not make use of the block write, the single byte
write is automatically used to write each byte from the block. There should
be no incompatibilities.
For example, printNumber already buffers, but then duplicates the
functionality of transmitting the bytes one at a time. It's simple to
change so the bytes are packed into the buffer in the correct order, so the
block write can be used:
void Print::printNumber(unsigned long n, uint8_t base, uint8_t sign)
{
uint8_t buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars.
uint8_t digit, i;
if (n == 0) {
buf[sizeof(buf) - 1] = '0';
i = sizeof(buf) - 1;
} else {
i = sizeof(buf) - 1;
while (1) {
digit = n % base;
buf[i] = ((digit < 10) ? '0' + digit : 'A' + digit
- 10);
n /= base;
if (n == 0) break;
i--;
}
}
if (sign) {
i--;
buf[i] = sign;
}
write(buf + i, sizeof(buf) - i);
}
This also includes packing the sign into the buffer. This it can be called
like this:
void Print::print(long n)
{
uint8_t sign=0;
if (n < 0) {
sign = '-';
n = -n;
}
printNumber(n, 10, sign);
}
void Print::print(unsigned long n)
{
printNumber(n, 10, 0);
}
Likewise, printing the newline is easy to change:
void Print::println(void)
{
uint8_t buf[2]={'\r', '\n'};
write(buf, 2);
}
Float printing requires a bit more effort, but it's also not too difficult
(especially if this already-tested code is just copied):
void Print::printFloat(double number, uint8_t digits)
{
uint8_t sign=0;
// Handle negative numbers
if (number < 0.0) {
sign = '-';
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
printNumber(int_part, 10, sign);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
uint8_t n, buf[5], count=1;
buf[0] = '.';
//write('.');
// Extract digits from the remainder one at a time
if (digits > sizeof(buf) - 1) digits = sizeof(buf) - 1;
while (digits-- > 0) {
remainder *= 10.0;
n = (uint8_t)(remainder);
buf[count++] = '0' + n;
remainder -= n;
}
write(buf, count);
}
}
Original issue reported on code.google.com by paul.sto...@gmail.com on 2 Jan 2010 at 12:48
Original issue reported on code.google.com by
paul.sto...@gmail.com
on 2 Jan 2010 at 12:48