/src/arduinojson/src/ArduinoJson/Memory/StringBuilder.hpp
Line | Count | Source |
1 | | // ArduinoJson - https://arduinojson.org |
2 | | // Copyright © 2014-2025, Benoit BLANCHON |
3 | | // MIT License |
4 | | |
5 | | #pragma once |
6 | | |
7 | | #include <ArduinoJson/Memory/ResourceManager.hpp> |
8 | | #include <ArduinoJson/Strings/JsonString.hpp> |
9 | | |
10 | | ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE |
11 | | |
12 | | class StringBuilder { |
13 | | public: |
14 | | static const size_t initialCapacity = 31; |
15 | | |
16 | 2.77k | StringBuilder(ResourceManager* resources) : resources_(resources) {} |
17 | | |
18 | 2.77k | ~StringBuilder() { |
19 | 2.77k | if (node_) |
20 | 934 | resources_->destroyString(node_); |
21 | 2.77k | } |
22 | | |
23 | 4.01k | void startString() { |
24 | 4.01k | size_ = 0; |
25 | 4.01k | if (!node_) |
26 | 1.68k | node_ = resources_->createString(initialCapacity); |
27 | 4.01k | } |
28 | | |
29 | 2.92k | void save(VariantData* variant) { |
30 | 2.92k | ARDUINOJSON_ASSERT(variant != nullptr); |
31 | 2.92k | ARDUINOJSON_ASSERT(node_ != nullptr); |
32 | | |
33 | 2.92k | char* p = node_->data; |
34 | 2.92k | if (isTinyString(p, size_)) { |
35 | 1.95k | variant->setTinyString(adaptString(p, size_)); |
36 | 1.95k | return; |
37 | 1.95k | } |
38 | | |
39 | 967 | p[size_] = 0; |
40 | 967 | StringNode* node = resources_->getString(adaptString(p, size_)); |
41 | 967 | if (!node) { |
42 | 754 | node = resources_->resizeString(node_, size_); |
43 | 754 | ARDUINOJSON_ASSERT(node != nullptr); // realloc to smaller can't fail |
44 | 754 | resources_->saveString(node); |
45 | 754 | node_ = nullptr; // next time we need a new string |
46 | 754 | } else { |
47 | 213 | node->references++; |
48 | 213 | } |
49 | 967 | variant->setLongString(node); |
50 | 967 | } |
51 | | |
52 | 0 | void append(const char* s) { |
53 | 0 | while (*s) |
54 | 0 | append(*s++); |
55 | 0 | } |
56 | | |
57 | 0 | void append(const char* s, size_t n) { |
58 | 0 | while (n-- > 0) // TODO: memcpy |
59 | 0 | append(*s++); |
60 | 0 | } |
61 | | |
62 | 13.2k | void append(char c) { |
63 | 13.2k | if (node_ && size_ == node_->length) |
64 | 156 | node_ = resources_->resizeString(node_, size_ * 2U + 1); |
65 | 13.2k | if (node_) |
66 | 13.2k | node_->data[size_++] = c; |
67 | 13.2k | } |
68 | | |
69 | 3.66k | bool isValid() const { |
70 | 3.66k | return node_ != nullptr; |
71 | 3.66k | } |
72 | | |
73 | 0 | size_t size() const { |
74 | 0 | return size_; |
75 | 0 | } |
76 | | |
77 | 2.53k | JsonString str() const { |
78 | 2.53k | ARDUINOJSON_ASSERT(node_ != nullptr); |
79 | 2.53k | node_->data[size_] = 0; |
80 | 2.53k | return JsonString(node_->data, size_); |
81 | 2.53k | } |
82 | | |
83 | | private: |
84 | | ResourceManager* resources_; |
85 | | StringNode* node_ = nullptr; |
86 | | size_t size_ = 0; |
87 | | }; |
88 | | |
89 | | ARDUINOJSON_END_PRIVATE_NAMESPACE |