Skip to content

Commit 6dc44aa

Browse files
committed
Modernize the README
1 parent a375445 commit 6dc44aa

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

README.md

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Read on to see how StreamUtils can help you!
3535
How to add buffering to a Stream?
3636
---------------------------------
3737

38+
> [!WARNING]
39+
> Adding a buffer only makes sense for **unbuffered** streams.
40+
> For example, there is **no benefit to adding a buffer to serial ports** because they already include an internal buffer.
41+
3842
### Buffering read operations
3943

4044
Sometimes, you can significantly improve performance by reading many bytes at once.
@@ -57,16 +61,16 @@ ReadBufferingStream bufferedFile{file, 64}; // <- HERE
5761
deserializeJson(doc, bufferedFile);
5862
```
5963

60-
Unfortunately, this optimization is only possible if:
61-
62-
1. `Stream.readBytes()` is declared `virtual` in your Arduino Code (as it's the case for ESP8266), and
63-
2. the derived class has an optimized implementation of `readBytes()` (as it's the case for SPIFFS' `File`).
64-
65-
When possible, prefer `ReadBufferingClient` to `ReadBufferingStream` because `Client` defines a `read()` method similar to `readBytes()`, except this one is `virtual` on all platforms.
66-
67-
If memory allocation fails, `ReadBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`.
64+
> [!IMPORTANT]
65+
> This optimization only works when:
66+
>
67+
> 1. `Stream::readBytes()` is declared `virtual` in the Arduino Core (as it's the case for ESP8266), and
68+
> 2. the derived class has an optimized implementation of `readBytes()` (as it's the case for SPIFFS' `File`).
69+
>
70+
> For this reason, **prefer `ReadBufferingClient` to `ReadBufferingStream`** because `Client::read()` is `virtual` on all platforms.
6871
69-
Adding a buffer only makes sense for **unbuffered** streams. For example, there is **no benefit to adding a buffer to serial ports** because they already include an internal buffer.
72+
> [!NOTE]
73+
> If memory allocation fails, `ReadBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`.
7074
7175
### Buffering write operations
7276

@@ -89,18 +93,21 @@ serializeJson(doc, bufferedWifiClient);
8993
bufferedWifiClient.flush();
9094
```
9195

92-
`flush()` sends the remaining data; if you forget to call it, the end of the message will be missing. The destructor of `WriteBufferingStream` calls `flush()`, so you can remove this line if you destroy the decorator immediately.
96+
> [!CAUTION]
97+
> `flush()` sends the remaining data; if you forget to call it, the end of the message will be missing.
9398
94-
If memory allocation fails, `WriteBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`.
99+
> [!TIP]
100+
> The destructor of `WriteBufferingStream` calls `flush()`, so you can remove this line if you destroy the decorator immediately.
95101
96-
Adding a buffer only makes sense for **unbuffered** streams. For example, there is **no benefit to adding a buffer to serial ports** because they already include an internal buffer.
102+
> [!NOTE]
103+
> If memory allocation fails, `WriteBufferingStream` behaves as if no buffer was used: it forwards all calls to the upstream `Stream`.
97104
98105
How to add logging to a stream?
99106
-------------------------------
100107

101108
### Logging write operations
102109

103-
When debugging a program that makes HTTP requests, you first want to check whether the request is correct. With this library, you can decorate the `EthernetClient` or the `WiFiClient` to log everything to the serial.
110+
When debugging a program that makes HTTP requests, you first want to check whether the request is correct. With this library, you can decorate `EthernetClient` or `WiFiClient` to log everything to the serial port.
104111

105112
![WriteLoggingStream](https://github.com/bblanchon/ArduinoStreamUtils/raw/master/extras/images/WriteLogger.svg)
106113

@@ -126,7 +133,7 @@ Everything you write to `loggingClient` is written to `client` and logged to `Se
126133
127134
### Logging read operations
128135
129-
Similarly, you often want to see what the HTTP server sent back. With this library, you can decorate the `EthernetClient` or the `WiFiClient` to log everything to the serial.
136+
Similarly, you often want to see what the HTTP server sent back. With this library, you can decorate `EthernetClient` or `WiFiClient` to log everything to the serial port.
130137
131138
![ReadLoggingStream](https://github.com/bblanchon/ArduinoStreamUtils/raw/master/extras/images/ReadLogger.svg)
132139
@@ -148,8 +155,9 @@ loggingClient.readBytes(response, 256);
148155
149156
`loggingClient` forwards all operations to `client` and logs read operations to `Serial`.
150157
151-
⚠ **WARNING** ⚠
152-
If your program receives data from one serial port and logs to another, **ensure the latter runs at a much higher baud rate**. Logging must be at least ten times faster, or it will slow down the receiving port, which may drop incoming bytes.
158+
> [!CAUTION]
159+
> If your program receives data from one serial port and logs to another, **ensure the latter runs at a much higher baud rate**.
160+
> Logging must be at least 10 times faster, or it will slow down the receiving port, which may drop incoming bytes.
153161
154162
### Logging read and write operations
155163
@@ -185,7 +193,7 @@ How to use error-correction codes (ECC)?
185193
StreamUtils supports the [Hamming(7, 4)](https://en.wikipedia.org/wiki/Hamming(7,4)) error-correction code, which encodes 4 bits of data into 7 bits by adding three parity bits.
186194
These extra bits increase the amount of traffic but allow correcting any one-bit error within the 7 bits.
187195
188-
If you use this encoding on an 8-bit channel, it effectively doubles the amount of traffic. However, if you use an [`HardwareSerial`](https://www.arduino.cc/reference/en/language/functions/communication/serial/) instance (like `Serial`, `Serial1`...), you can slightly reduce the overhead by configuring the ports as a 7-bit channel, like so:
196+
If you use this encoding on an 8-bit channel, it effectively doubles the amount of traffic. However, if you use a [`HardwareSerial`](https://www.arduino.cc/reference/en/language/functions/communication/serial/) instance (like `Serial`, `Serial1`...), you can slightly reduce the overhead by configuring the ports as a 7-bit channel, like so:
189197
190198
```c++
191199
// Initialize serial port with 9600 bauds, 7 bits of data, no parity, and one stop bit
@@ -269,7 +277,9 @@ wireStream.print("This is a very very long message that I'm sending!");
269277
Wire.endTransmission();
270278
```
271279

272-
As you can see, we use the `wait()` function as a hook to flush the Wire transmission buffer. Notice that we pass `false` to [`endTransmission()`](https://www.arduino.cc/en/Reference/WireEndTransmission) so that it sends the data but doesn't actually stop the transmission.
280+
> [!NOTE]
281+
> We use the `wait()` function as a hook to flush the Wire transmission buffer.
282+
> Notice that we pass `false` to [`endTransmission()`](https://www.arduino.cc/en/Reference/WireEndTransmission) so that it sends the data but doesn't actually stop the transmission.
273283
274284

275285
How to use a `String` as a stream?
@@ -302,7 +312,7 @@ Temperature = 22.30 °C
302312

303313
### Reading from a `String`
304314

305-
Similarly, there are cases where you have a `String`, but you need to pass a `Stream` to some other piece of code. In that case, use `StringStream`; it's similar to `StrintPrint`, except you can also read from it.
315+
Similarly, there are cases where you have a `String`, but you need to pass a `Stream` to some other piece of code. In that case, use `StringStream`; it's similar to `StringPrint`, except you can also read from it.
306316

307317
![StringStream](https://github.com/bblanchon/ArduinoStreamUtils/raw/master/extras/images/StringStream.svg)
308318

@@ -350,7 +360,7 @@ Serial.println(stream.readString());
350360
How to decode HTTP chunks?
351361
--------------------------
352362
353-
HTTP servers can send their response in multiple parts using [Chunked Transfer Encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding). Clients using HTTP 1.1 must support this encoding as it's not optional and is dictated by the server.
363+
HTTP servers can send responses in multiple parts using [Chunked Transfer Encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding). Clients using HTTP 1.1 must support this encoding as it's not optional and is dictated by the server.
354364
355365
`ChunkDecodingStream` and `ChunkDecodingClient` are decorators that decode the chunks and make the response available as a regular stream.
356366
@@ -387,9 +397,13 @@ deserializeJson(doc, response);
387397
http.end();
388398
```
389399

390-
Note that `HTTPClient` already performs chunk decoding **if** you use `getString()`, but you might want to use `getStream()` to avoid buffering the entire response in memory.
400+
> [!WARNING]
401+
> `HTTPClient` already performs chunk decoding when you use `getString()`.
402+
> Only use `ChunkDecodingStream` if you use `getStream()` as in the example above.
391403
392-
Also, you can avoid chunked transfer encoding by downgrading the HTTP version to 1.0. `HTTPClient` allows you to do that by calling `useHTTP10(true)` before sending the request.
404+
> [!TIP]
405+
> You can avoid chunked transfer encoding by downgrading the HTTP version to 1.0.
406+
> `HTTPClient` does this if you call `useHTTP10(true)` before sending the request.
393407
394408
Summary
395409
-------
@@ -413,7 +427,8 @@ See the equivalence table below.
413427
| Error correction (encode & decode) | `HammingClient` | `HammingStream` | |
414428
| Decode HTTP chunks | `ChunkDecodingClient` | `ChunkDecodingStream` | |
415429

416-
Prefer `XxxClient` to `XxxStream` because, unlike `Stream::readBytes()`, `Client::read()` is virtual on all cores and therefore allows optimized implementations.
430+
> [!TIP]
431+
> Prefer `XxxClient` to `XxxStream` because, unlike `Stream::readBytes()`, `Client::read()` is virtual on all cores and therefore allows optimized implementations.
417432
418433

419434
Portability
@@ -436,5 +451,6 @@ It has been tested on the following cores:
436451
* [STM32 Roger's Core](https://github.com/rogerclarkmelbourne/Arduino_STM32) (no EEPROM support)
437452
* [Teensy](https://github.com/PaulStoffregen/cores)
438453

439-
If your core is not supported, please [open an issue](https://github.com/bblanchon/ArduinoStreamUtils/issues/new).
440-
Thank you for your understanding.
454+
> [!IMPORTANT]
455+
> Each Arduino Core includes subtle variations that I cannot anticipate.
456+
> If the build fails, please [open an issue](https://github.com/bblanchon/ArduinoStreamUtils/issues/new), so I can update the library.

0 commit comments

Comments
 (0)