Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
CollectionImpl.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <ArduinoJson/Collection/CollectionData.hpp> 00008 #include <ArduinoJson/Variant/VariantData.hpp> 00009 00010 namespace ARDUINOJSON_NAMESPACE { 00011 00012 inline bool variantEquals(const VariantData* a, const VariantData* b) { 00013 return variantCompare(a, b) == COMPARE_RESULT_EQUAL; 00014 } 00015 00016 inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) { 00017 VariantSlot* slot = pool->allocVariant(); 00018 if (!slot) 00019 return 0; 00020 00021 if (_tail) { 00022 _tail->setNextNotNull(slot); 00023 _tail = slot; 00024 } else { 00025 _head = slot; 00026 _tail = slot; 00027 } 00028 00029 slot->clear(); 00030 return slot; 00031 } 00032 00033 inline VariantData* CollectionData::addElement(MemoryPool* pool) { 00034 return slotData(addSlot(pool)); 00035 } 00036 00037 template <typename TAdaptedString> 00038 inline VariantData* CollectionData::addMember(TAdaptedString key, 00039 MemoryPool* pool) { 00040 VariantSlot* slot = addSlot(pool); 00041 if (!slotSetKey(slot, key, pool)) { 00042 removeSlot(slot); 00043 return 0; 00044 } 00045 return slot->data(); 00046 } 00047 00048 inline void CollectionData::clear() { 00049 _head = 0; 00050 _tail = 0; 00051 } 00052 00053 template <typename TAdaptedString> 00054 inline bool CollectionData::containsKey(const TAdaptedString& key) const { 00055 return getSlot(key) != 0; 00056 } 00057 00058 inline bool CollectionData::copyFrom(const CollectionData& src, 00059 MemoryPool* pool) { 00060 clear(); 00061 for (VariantSlot* s = src._head; s; s = s->next()) { 00062 VariantData* var; 00063 if (s->key() != 0) { 00064 if (s->ownsKey()) 00065 var = addMember(RamStringAdapter(s->key()), pool); 00066 else 00067 var = addMember(ConstRamStringAdapter(s->key()), pool); 00068 } else { 00069 var = addElement(pool); 00070 } 00071 if (!var) 00072 return false; 00073 if (!var->copyFrom(*s->data(), pool)) 00074 return false; 00075 } 00076 return true; 00077 } 00078 00079 inline bool CollectionData::equalsObject(const CollectionData& other) const { 00080 size_t count = 0; 00081 for (VariantSlot* slot = _head; slot; slot = slot->next()) { 00082 VariantData* v1 = slot->data(); 00083 VariantData* v2 = other.getMember(adaptString(slot->key())); 00084 if (!variantEquals(v1, v2)) 00085 return false; 00086 count++; 00087 } 00088 return count == other.size(); 00089 } 00090 00091 inline bool CollectionData::equalsArray(const CollectionData& other) const { 00092 VariantSlot* s1 = _head; 00093 VariantSlot* s2 = other._head; 00094 for (;;) { 00095 if (s1 == s2) 00096 return true; 00097 if (!s1 || !s2) 00098 return false; 00099 if (!variantEquals(s1->data(), s2->data())) 00100 return false; 00101 s1 = s1->next(); 00102 s2 = s2->next(); 00103 } 00104 } 00105 00106 template <typename TAdaptedString> 00107 inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { 00108 VariantSlot* slot = _head; 00109 while (slot) { 00110 if (key.equals(slot->key())) 00111 break; 00112 slot = slot->next(); 00113 } 00114 return slot; 00115 } 00116 00117 inline VariantSlot* CollectionData::getSlot(size_t index) const { 00118 return _head->next(index); 00119 } 00120 00121 inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { 00122 VariantSlot* current = _head; 00123 while (current) { 00124 VariantSlot* next = current->next(); 00125 if (next == target) 00126 return current; 00127 current = next; 00128 } 00129 return 0; 00130 } 00131 00132 template <typename TAdaptedString> 00133 inline VariantData* CollectionData::getMember(TAdaptedString key) const { 00134 VariantSlot* slot = getSlot(key); 00135 return slot ? slot->data() : 0; 00136 } 00137 00138 template <typename TAdaptedString> 00139 inline VariantData* CollectionData::getOrAddMember(TAdaptedString key, 00140 MemoryPool* pool) { 00141 // ignore null key 00142 if (key.isNull()) 00143 return 0; 00144 00145 // search a matching key 00146 VariantSlot* slot = getSlot(key); 00147 if (slot) 00148 return slot->data(); 00149 00150 return addMember(key, pool); 00151 } 00152 00153 inline VariantData* CollectionData::getElement(size_t index) const { 00154 VariantSlot* slot = getSlot(index); 00155 return slot ? slot->data() : 0; 00156 } 00157 00158 inline VariantData* CollectionData::getOrAddElement(size_t index, 00159 MemoryPool* pool) { 00160 VariantSlot* slot = _head; 00161 while (slot && index > 0) { 00162 slot = slot->next(); 00163 index--; 00164 } 00165 if (!slot) 00166 index++; 00167 while (index > 0) { 00168 slot = addSlot(pool); 00169 index--; 00170 } 00171 return slotData(slot); 00172 } 00173 00174 inline void CollectionData::removeSlot(VariantSlot* slot) { 00175 if (!slot) 00176 return; 00177 VariantSlot* prev = getPreviousSlot(slot); 00178 VariantSlot* next = slot->next(); 00179 if (prev) 00180 prev->setNext(next); 00181 else 00182 _head = next; 00183 if (!next) 00184 _tail = prev; 00185 } 00186 00187 inline void CollectionData::removeElement(size_t index) { 00188 removeSlot(getSlot(index)); 00189 } 00190 00191 inline size_t CollectionData::memoryUsage() const { 00192 size_t total = 0; 00193 for (VariantSlot* s = _head; s; s = s->next()) { 00194 total += sizeof(VariantSlot) + s->data()->memoryUsage(); 00195 if (s->ownsKey()) 00196 total += strlen(s->key()) + 1; 00197 } 00198 return total; 00199 } 00200 00201 inline size_t CollectionData::nesting() const { 00202 size_t maxChildNesting = 0; 00203 for (VariantSlot* s = _head; s; s = s->next()) { 00204 size_t childNesting = s->data()->nesting(); 00205 if (childNesting > maxChildNesting) 00206 maxChildNesting = childNesting; 00207 } 00208 return maxChildNesting + 1; 00209 } 00210 00211 inline size_t CollectionData::size() const { 00212 return slotSize(_head); 00213 } 00214 00215 template <typename T> 00216 inline void movePointer(T*& p, ptrdiff_t offset) { 00217 if (!p) 00218 return; 00219 p = reinterpret_cast<T*>( 00220 reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset)); 00221 ARDUINOJSON_ASSERT(isAligned(p)); 00222 } 00223 00224 inline void CollectionData::movePointers(ptrdiff_t stringDistance, 00225 ptrdiff_t variantDistance) { 00226 movePointer(_head, variantDistance); 00227 movePointer(_tail, variantDistance); 00228 for (VariantSlot* slot = _head; slot; slot = slot->next()) 00229 slot->movePointers(stringDistance, variantDistance); 00230 } 00231 00232 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:36 by
1.7.2