2017-01-06 21:07:34 +01:00
|
|
|
// Copyright Benoit Blanchon 2014-2017
|
2014-11-11 16:41:45 +01:00
|
|
|
// MIT License
|
|
|
|
//
|
|
|
|
// Arduino JSON library
|
|
|
|
// https://github.com/bblanchon/ArduinoJson
|
2016-01-07 22:35:12 +01:00
|
|
|
// If you like this project, please add a star!
|
2014-11-08 19:40:07 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "IndentedPrint.hpp"
|
|
|
|
|
|
|
|
namespace ArduinoJson {
|
|
|
|
namespace Internals {
|
|
|
|
|
|
|
|
// Converts a compact JSON string into an indented one.
|
|
|
|
class Prettyfier : public Print {
|
|
|
|
public:
|
2014-11-11 16:41:45 +01:00
|
|
|
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
|
2014-11-08 19:40:07 +01:00
|
|
|
_previousChar = 0;
|
|
|
|
_inString = false;
|
|
|
|
}
|
|
|
|
|
2016-06-22 21:41:19 +02:00
|
|
|
virtual size_t write(uint8_t c) {
|
|
|
|
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
|
|
|
|
_previousChar = c;
|
|
|
|
return n;
|
|
|
|
}
|
2014-11-08 19:40:07 +01:00
|
|
|
|
|
|
|
private:
|
2014-11-11 18:18:26 +01:00
|
|
|
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
|
2014-11-08 19:40:07 +01:00
|
|
|
|
2016-06-22 21:41:19 +02:00
|
|
|
bool inEmptyBlock() {
|
|
|
|
return _previousChar == '{' || _previousChar == '[';
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t handleStringChar(uint8_t c) {
|
|
|
|
bool isQuote = c == '"' && _previousChar != '\\';
|
|
|
|
|
|
|
|
if (isQuote) _inString = false;
|
|
|
|
|
|
|
|
return _sink.write(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t handleMarkupChar(uint8_t c) {
|
|
|
|
switch (c) {
|
|
|
|
case '{':
|
|
|
|
case '[':
|
|
|
|
return writeBlockOpen(c);
|
|
|
|
|
|
|
|
case '}':
|
|
|
|
case ']':
|
|
|
|
return writeBlockClose(c);
|
2014-11-08 19:40:07 +01:00
|
|
|
|
2016-06-22 21:41:19 +02:00
|
|
|
case ':':
|
|
|
|
return writeColon();
|
2014-11-08 19:40:07 +01:00
|
|
|
|
2016-06-22 21:41:19 +02:00
|
|
|
case ',':
|
|
|
|
return writeComma();
|
|
|
|
|
|
|
|
case '"':
|
|
|
|
return writeQuoteOpen();
|
|
|
|
|
|
|
|
default:
|
|
|
|
return writeNormalChar(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeBlockClose(uint8_t c) {
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += unindentIfNeeded();
|
|
|
|
n += _sink.write(c);
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeBlockOpen(uint8_t c) {
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += indentIfNeeded();
|
|
|
|
n += _sink.write(c);
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeColon() {
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += _sink.write(':');
|
|
|
|
n += _sink.write(' ');
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeComma() {
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += _sink.write(',');
|
|
|
|
n += _sink.println();
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeQuoteOpen() {
|
|
|
|
_inString = true;
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += indentIfNeeded();
|
|
|
|
n += _sink.write('"');
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t writeNormalChar(uint8_t c) {
|
2016-09-17 13:51:54 +02:00
|
|
|
size_t n = 0;
|
|
|
|
n += indentIfNeeded();
|
|
|
|
n += _sink.write(c);
|
|
|
|
return n;
|
2016-06-22 21:41:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t indentIfNeeded() {
|
|
|
|
if (!inEmptyBlock()) return 0;
|
|
|
|
|
|
|
|
_sink.indent();
|
|
|
|
return _sink.println();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t unindentIfNeeded() {
|
|
|
|
if (inEmptyBlock()) return 0;
|
|
|
|
|
|
|
|
_sink.unindent();
|
|
|
|
return _sink.println();
|
|
|
|
}
|
2014-11-11 18:18:26 +01:00
|
|
|
|
|
|
|
uint8_t _previousChar;
|
|
|
|
IndentedPrint& _sink;
|
|
|
|
bool _inString;
|
2014-11-08 19:40:07 +01:00
|
|
|
};
|
|
|
|
}
|
2014-11-11 16:41:45 +01:00
|
|
|
}
|