StringWriter.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2025, Benoit BLANCHON
  3. // MIT License
  4. #include <Arduino.h>
  5. #define ARDUINOJSON_STRING_BUFFER_SIZE 5
  6. #include <ArduinoJson.h>
  7. #include <catch.hpp>
  8. #include "Literals.hpp"
  9. #include "custom_string.hpp"
  10. using namespace ArduinoJson::detail;
  11. template <typename StringWriter>
  12. static size_t print(StringWriter& writer, const char* s) {
  13. return writer.write(reinterpret_cast<const uint8_t*>(s), strlen(s));
  14. }
  15. template <typename StringWriter>
  16. static size_t print(StringWriter& writer, char c) {
  17. return writer.write(static_cast<uint8_t>(c));
  18. }
  19. template <typename StringWriter, typename String>
  20. void common_tests(StringWriter& writer, const String& output) {
  21. SECTION("InitialState") {
  22. REQUIRE(std::string("") == output);
  23. }
  24. SECTION("EmptyString") {
  25. REQUIRE(0 == print(writer, ""));
  26. REQUIRE(std::string("") == output);
  27. }
  28. SECTION("OneString") {
  29. REQUIRE(4 == print(writer, "ABCD"));
  30. REQUIRE("ABCD"_s == output);
  31. }
  32. SECTION("TwoStrings") {
  33. REQUIRE(4 == print(writer, "ABCD"));
  34. REQUIRE(4 == print(writer, "EFGH"));
  35. REQUIRE("ABCDEFGH"_s == output);
  36. }
  37. }
  38. TEST_CASE("StaticStringWriter") {
  39. char output[20] = {0};
  40. StaticStringWriter writer(output, sizeof(output));
  41. common_tests(writer, static_cast<const char*>(output));
  42. SECTION("OverCapacity") {
  43. REQUIRE(20 == print(writer, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
  44. REQUIRE(0 == print(writer, "ABC"));
  45. REQUIRE(0 == print(writer, 'D'));
  46. REQUIRE("ABCDEFGHIJKLMNOPQRST" == std::string(output, 20));
  47. }
  48. }
  49. TEST_CASE("Writer<std::string>") {
  50. std::string output;
  51. Writer<std::string> writer(output);
  52. common_tests(writer, output);
  53. }
  54. TEST_CASE("Writer<String>") {
  55. ::String output;
  56. Writer<::String> writer(output);
  57. SECTION("write(char)") {
  58. SECTION("writes to temporary buffer") {
  59. // accumulate in buffer
  60. writer.write('a');
  61. writer.write('b');
  62. writer.write('c');
  63. writer.write('d');
  64. REQUIRE(output == "");
  65. // flush when full
  66. writer.write('e');
  67. REQUIRE(output == "abcd");
  68. // flush on destruction
  69. writer.write('f');
  70. writer.~Writer();
  71. REQUIRE(output == "abcdef");
  72. }
  73. SECTION("returns 1 on success") {
  74. for (int i = 0; i < ARDUINOJSON_STRING_BUFFER_SIZE; i++) {
  75. REQUIRE(writer.write('x') == 1);
  76. }
  77. }
  78. SECTION("returns 0 on error") {
  79. output.limitCapacityTo(1);
  80. REQUIRE(writer.write('a') == 1);
  81. REQUIRE(writer.write('b') == 1);
  82. REQUIRE(writer.write('c') == 1);
  83. REQUIRE(writer.write('d') == 1);
  84. REQUIRE(writer.write('e') == 0);
  85. REQUIRE(writer.write('f') == 0);
  86. }
  87. }
  88. SECTION("write(char*, size_t)") {
  89. SECTION("empty string") {
  90. REQUIRE(0 == print(writer, ""));
  91. writer.flush();
  92. REQUIRE(output == "");
  93. }
  94. SECTION("writes to temporary buffer") {
  95. // accumulate in buffer
  96. print(writer, "abc");
  97. REQUIRE(output == "");
  98. // flush when full, and continue to accumulate
  99. print(writer, "de");
  100. REQUIRE(output == "abcd");
  101. // flush on destruction
  102. writer.~Writer();
  103. REQUIRE(output == "abcde");
  104. }
  105. }
  106. }
  107. TEST_CASE("Writer<custom_string>") {
  108. custom_string output;
  109. Writer<custom_string> writer(output);
  110. REQUIRE(4 == print(writer, "ABCD"));
  111. REQUIRE("ABCD" == output);
  112. }
  113. TEST_CASE("serializeJson(doc, String)") {
  114. JsonDocument doc;
  115. doc["hello"] = "world";
  116. ::String output = "erase me";
  117. SECTION("sufficient capacity") {
  118. serializeJson(doc, output);
  119. REQUIRE(output == "{\"hello\":\"world\"}");
  120. }
  121. SECTION("unsufficient capacity") { // issue #1561
  122. output.limitCapacityTo(10);
  123. serializeJson(doc, output);
  124. REQUIRE(output == "{\"hello\"");
  125. }
  126. }