JsonFormatter.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef json_formatter_h | ||
| 2 | #define json_formatter_h | ||
| 3 | #include <Arduino.h> | ||
| 4 | |||
| 5 | // Where a formatter's output stands, to go back to when what follows doesn't | ||
| 6 | // fit (JsonFormatter::mark()). | ||
| 7 | struct json_mark_t { | ||
| 8 | size_t len; | ||
| 9 | uint8_t objects; | ||
| 10 | uint8_t arrays; | ||
| 11 | bool nocomma; | ||
| 12 | }; | ||
| 13 | |||
| 14 | // Streams JSON into a fixed buffer. Free of the web server so it can be unit | ||
| 15 | // tested on the PC (pio test -e native). | ||
| 16 | class JsonFormatter { | ||
| 17 | protected: | ||
| 18 | char *buff; | ||
| 19 | size_t buffSize; | ||
| 20 | // What is in buff, kept so appending never has to strlen() the buffer. | ||
| 21 | size_t _len = 0; | ||
| 22 | bool _headersSent = false; | ||
| 23 | uint8_t _objects = 0; | ||
| 24 | uint8_t _arrays = 0; | ||
| 25 | bool _nocomma = true; | ||
| 26 | // Something didn't fit and was left out so the JSON is incomplete. | ||
| 27 | bool _overflow = false; | ||
| 28 | // Whether running out of room is logged. | ||
| 29 | bool _logOverflow = true; | ||
| 30 | char _numbuff[25] = {0}; | ||
| 31 | virtual void _safecat(const char *val, bool escape = false); | ||
| 32 | // Appends val at buff + _len. vlen is what it takes, including the quotes | ||
| 33 | // when escaped; the caller has made sure it fits. | ||
| 34 | void _appendAt(const char *val, bool escape, size_t vlen); | ||
| 35 | void _appendNumber(const char *name); | ||
| 36 | public: | ||
| 37 | 501 | bool overflowed() const { return _overflow; } | |
| 38 | 701 | json_mark_t mark() const { return {_len, _objects, _arrays, _nocomma}; } | |
| 39 | // Drops everything written since m, an overflow included. | ||
| 40 | void rollback(const json_mark_t &m); | ||
| 41 | // A writer that tries an item and rolls back when it doesn't fit turns the | ||
| 42 | // overflow log off, as running out of room is expected there. | ||
| 43 | 43 | void logOverflow(bool on) { _logOverflow = on; } | |
| 44 | // Drops whatever is written until a buffer is set again. Nothing is | ||
| 45 | // written anywhere, so tasks can share one discarding formatter. | ||
| 46 | void discard(); | ||
| 47 | // Writes c as it must appear inside a JSON string (out needs 7 bytes) and | ||
| 48 | // returns its length. | ||
| 49 | static size_t escapeChar(char c, char *out); | ||
| 50 | void escapeString(const char *raw, char *escaped); | ||
| 51 | uint32_t calcEscapedLength(const char *raw); | ||
| 52 | void beginObject(const char *name = nullptr); | ||
| 53 | void endObject(); | ||
| 54 | void beginArray(const char *name = nullptr); | ||
| 55 | void endArray(); | ||
| 56 | void appendElem(const char *name = nullptr); | ||
| 57 | |||
| 58 | void addElem(const char* val); | ||
| 59 | void addElem(float fval); | ||
| 60 | void addElem(int8_t nval); | ||
| 61 | void addElem(uint8_t nval); | ||
| 62 | /* | ||
| 63 | void addElem(int32_t nval); | ||
| 64 | void addElem(int16_t nval); | ||
| 65 | void addElem(uint16_t nval); | ||
| 66 | void addElem(unsigned int nval); | ||
| 67 | */ | ||
| 68 | void addElem(int32_t lval); | ||
| 69 | void addElem(uint32_t lval); | ||
| 70 | void addElem(bool bval); | ||
| 71 | |||
| 72 | void addElem(const char* name, float fval); | ||
| 73 | void addElem(const char* name, int8_t nval); | ||
| 74 | void addElem(const char* name, uint8_t nval); | ||
| 75 | /* | ||
| 76 | void addElem(const char* name, int nval); | ||
| 77 | void addElem(const char* name, int16_t nval); | ||
| 78 | void addElem(const char* name, uint16_t nval); | ||
| 79 | void addElem(const char* name, unsigned int nval); | ||
| 80 | */ | ||
| 81 | void addElem(const char* name, int32_t lval); | ||
| 82 | void addElem(const char* name, uint32_t lval); | ||
| 83 | void addElem(const char* name, bool bval); | ||
| 84 | void addElem(const char *name, const char *val); | ||
| 85 | void addElem(const char* name, uint64_t lval); | ||
| 86 | }; | ||
| 87 | class BufferedJsonFormatter : public JsonFormatter { | ||
| 88 | public: | ||
| 89 | void setBuffer(char *b, size_t sz); | ||
| 90 | size_t length() const; | ||
| 91 | }; | ||
| 92 | #endif | ||
| 93 |