StringBuffer.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2025, Benoit BLANCHON
  3. // MIT License
  4. #pragma once
  5. #include <ArduinoJson/Memory/ResourceManager.hpp>
  6. ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
  7. class StringBuffer {
  8. public:
  9. StringBuffer(ResourceManager* resources) : resources_(resources) {}
  10. ~StringBuffer() {
  11. if (node_)
  12. resources_->destroyString(node_);
  13. }
  14. char* reserve(size_t capacity) {
  15. if (node_ && capacity > node_->length) {
  16. // existing buffer is too small, we need to reallocate
  17. resources_->destroyString(node_);
  18. node_ = nullptr;
  19. }
  20. if (!node_)
  21. node_ = resources_->createString(capacity);
  22. if (!node_)
  23. return nullptr;
  24. size_ = capacity;
  25. node_->data[capacity] = 0; // null-terminate the string
  26. return node_->data;
  27. }
  28. JsonString str() const {
  29. ARDUINOJSON_ASSERT(node_ != nullptr);
  30. return JsonString(node_->data, node_->length);
  31. }
  32. void save(VariantData* data) {
  33. ARDUINOJSON_ASSERT(node_ != nullptr);
  34. const char* s = node_->data;
  35. if (isTinyString(s, size_))
  36. data->setTinyString(adaptString(s, size_));
  37. else
  38. data->setOwnedString(commitStringNode());
  39. }
  40. void saveRaw(VariantData* data) {
  41. data->setRawString(commitStringNode());
  42. }
  43. private:
  44. StringNode* commitStringNode() {
  45. ARDUINOJSON_ASSERT(node_ != nullptr);
  46. node_->data[size_] = 0;
  47. auto node = resources_->getString(adaptString(node_->data, size_));
  48. if (node) {
  49. node->references++;
  50. return node;
  51. }
  52. if (node_->length != size_) {
  53. node = resources_->resizeString(node_, size_);
  54. ARDUINOJSON_ASSERT(node != nullptr); // realloc to smaller can't fail
  55. } else {
  56. node = node_;
  57. }
  58. node_ = nullptr;
  59. resources_->saveString(node);
  60. return node;
  61. }
  62. ResourceManager* resources_;
  63. StringNode* node_ = nullptr;
  64. size_t size_ = 0;
  65. };
  66. ARDUINOJSON_END_PRIVATE_NAMESPACE