ArduinoJson 6.13.0: custom reader and writer
01 November 2019
ArduinoJson 6.13.0 is out! This version fixes several bugs and adds a new feature: custom reader and writer classes.
Custom reader
As you know, ArduinoJson natively supports several input types:
const char*
char*
const __FlashStringHelper*
Stream
String
std::istream
std::string
But how do you deal with other input types?
In the previous versions of ArduinoJson, you had to derive a class from either Stream
or std::stream
. This solution works but is heavy: your class inherits from much unnecessary stuff, and each call requires a virtual dispatch.
ArduinoJson 6.13.0 offers a lightweight solution: the custom reader class. This class doesn’t have to inherit from anything; it simply needs to implement two member functions with the right signatures. Here is what it should look like:
struct CustomReader {
// Reads one byte, or returns -1
int read();
// Reads several bytes, returns the number of bytes read.
size_t readBytes(char* buffer, size_t length);
};
As you can see, these two functions are inspired by the virtual functions from Arduino’s Stream
class. In this case, however, the functions don’t need to be virtual because ArduinoJson uses static dispatch to call them.
You can pass an instance of this class to the deserialization functions:
Custom writer
Similarly, ArduinoJson natively supports several output types:
char*
Print
String
std::ostream
std::string
To use an unsupported output type, you had to derive a class from Print
or std::ostream
; again, a heavyweight solution. Here too, ArduinoJson 6.13.0 allows using a custom class to adapt the output type for the library.
Like the custom reader class, the custom writer class doesn’t need to inherit from anything; it just needs to implement two functions. Here is how it looks like:
struct CustomWriter {
// Writes one byte, returns the number of bytes written (0 or 1)
size_t write(uint8_t c);
// Writes several bytes, returns the number of bytes written
size_t write(const uint8_t *buffer, size_t length);
};
This time, the signatures mimic the virtual function from Arduino’s Print
class. Again, they don’t need to be virtual because ArduinoJson resolves the names at compile-time.
You can pass an instance of this class to the serialization functions:
Conclusion
I know very few people will use this feature, but it will greatly improve the few projects that need it.
In hindsight, I wish I hadn’t reused the signatures from Stream
and Print
because they are not symmetric (both in names and types). Well, it’s too late now.
That’s all I needed to say about this release. As usual, please open an issue on GitHub. If you haven’t already, please add a star to support the project ;-)