arduino / arduino/ArduinoCore-avr

Print class to use block write [imported]

Open
#230 0 comments 0 reactions 1 assignee Claimed by @cmaglie View on GitHub
Dominant language
C
Stars
1.5k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

This is [Issue 164](http://code.google.com/p/arduino/issues/detail?id=164) moved from a Google Code project.
Added by 2010-01-02T00:48:44.000Z by [paul.sto...@gmail.com](http://code.google.com/u/102276914943260257800/).
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Enhancement, Priority-Medium
### Original description

**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:

``` C++
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:

``` C++
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):

``` C++
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 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);
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.