diff --git a/Bag-of-Tricks.md b/Bag-of-Tricks.md index 8139ee8..1ae37b4 100644 --- a/Bag-of-Tricks.md +++ b/Bag-of-Tricks.md @@ -168,7 +168,7 @@ merge(nestedObject, jsonObjectTwo); See issue [#332](https://github.com/bblanchon/ArduinoJson/issues/332) -## Buffered output: +## Buffered output Here is a proxy that will put bytes in a buffer before actually writing them to the destination: @@ -247,6 +247,88 @@ root.printTo(chunkPrint); See issue [#206](https://github.com/bblanchon/ArduinoJson/issues/206). +## Render to ESP8266 WiFiClient + +When used on [ESP8266 Arduino](https://github.com/esp8266/Arduino), there is currently not a direct way to render the JSON to WiFiClient, since it does not implement required Print interface. +This utility class serves as bridge between Print and WiFiClient classes. Internal buffer is required, otherwise rendering will take several seconds (every byte will be sent as separate packet). Increase buffer for faster send, if you have spare memory. + +Create this as separate header file `WiFiClientPrint.h` or just include class in your program. + +_Note: You need to call either `flush()` or `stop()` manually after printTo._ + +```c++ +#pragma once + +#include +#include + +template +class WiFiClientPrint : public Print +{ + public: + WiFiClientPrint(WiFiClient client) + : _client(client), + _length(0) + { + } + + ~WiFiClientPrint() + { +#ifdef DEBUG_ESP_PORT + // Note: This is manual expansion of assertion macro + if (_length != 0) { + DEBUG_ESP_PORT.printf("\nassertion failed at " __FILE__ ":%d: " "_length == 0" "\n", __LINE__); + // Note: abort() causes stack dump and restart of the ESP + abort(); + } +#endif + } + + virtual size_t write(uint8_t c) override + { + _buffer[_length++] = c; + if (_length == BUFFER_SIZE) { + flush(); + } + } + + void flush() + { + if (_length != 0) { + _client.write((const uint8_t*)_buffer, _length); + _length = 0; + } + } + + void stop() + { + flush(); + _client.stop(); + } + + private: + WiFiClient _client; + uint8_t _buffer[BUFFER_SIZE]; + size_t _length; +}; +``` + +Usage (typically inside `ESP8266WebServer` handler): +```c++ +// #include "WiFiClientPrint.h" + +// ESP8266WebServer _server; +// JsonObject json; +_server.setContentLength(json.measureLength()); +_server.send(200, "application/json", ""); + +WiFiClientPrint<> p(_server.client()); +json.printTo(p); +p.stop(); // Calls p.flush() and WifiClient.stop() +``` + +See issue [#166](https://github.com/bblanchon/ArduinoJson/issues/166). + ## Compute hash of JSON output Here is how you can compute the CRC32 hash of the JSON output without consuming a lot of memory.