Prettyfier.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright Benoit Blanchon 2014-2016
  2. // MIT License
  3. //
  4. // Arduino JSON library
  5. // https://github.com/bblanchon/ArduinoJson
  6. // If you like this project, please add a star!
  7. #pragma once
  8. #include "IndentedPrint.hpp"
  9. namespace ArduinoJson {
  10. namespace Internals {
  11. // Converts a compact JSON string into an indented one.
  12. class Prettyfier : public Print {
  13. public:
  14. explicit Prettyfier(IndentedPrint& p) : _sink(p) {
  15. _previousChar = 0;
  16. _inString = false;
  17. }
  18. virtual size_t write(uint8_t c) {
  19. size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
  20. _previousChar = c;
  21. return n;
  22. }
  23. private:
  24. Prettyfier& operator=(const Prettyfier&); // cannot be assigned
  25. bool inEmptyBlock() {
  26. return _previousChar == '{' || _previousChar == '[';
  27. }
  28. size_t handleStringChar(uint8_t c) {
  29. bool isQuote = c == '"' && _previousChar != '\\';
  30. if (isQuote) _inString = false;
  31. return _sink.write(c);
  32. }
  33. size_t handleMarkupChar(uint8_t c) {
  34. switch (c) {
  35. case '{':
  36. case '[':
  37. return writeBlockOpen(c);
  38. case '}':
  39. case ']':
  40. return writeBlockClose(c);
  41. case ':':
  42. return writeColon();
  43. case ',':
  44. return writeComma();
  45. case '"':
  46. return writeQuoteOpen();
  47. default:
  48. return writeNormalChar(c);
  49. }
  50. }
  51. size_t writeBlockClose(uint8_t c) {
  52. size_t n = 0;
  53. n += unindentIfNeeded();
  54. n += _sink.write(c);
  55. return n;
  56. }
  57. size_t writeBlockOpen(uint8_t c) {
  58. size_t n = 0;
  59. n += indentIfNeeded();
  60. n += _sink.write(c);
  61. return n;
  62. }
  63. size_t writeColon() {
  64. size_t n = 0;
  65. n += _sink.write(':');
  66. n += _sink.write(' ');
  67. return n;
  68. }
  69. size_t writeComma() {
  70. size_t n = 0;
  71. n += _sink.write(',');
  72. n += _sink.println();
  73. return n;
  74. }
  75. size_t writeQuoteOpen() {
  76. _inString = true;
  77. size_t n = 0;
  78. n += indentIfNeeded();
  79. n += _sink.write('"');
  80. return n;
  81. }
  82. size_t writeNormalChar(uint8_t c) {
  83. size_t n = 0;
  84. n += indentIfNeeded();
  85. n += _sink.write(c);
  86. return n;
  87. }
  88. size_t indentIfNeeded() {
  89. if (!inEmptyBlock()) return 0;
  90. _sink.indent();
  91. return _sink.println();
  92. }
  93. size_t unindentIfNeeded() {
  94. if (inEmptyBlock()) return 0;
  95. _sink.unindent();
  96. return _sink.println();
  97. }
  98. uint8_t _previousChar;
  99. IndentedPrint& _sink;
  100. bool _inString;
  101. };
  102. }
  103. }