Fixed copyArray() not working with MemberProxy and ElementProxy

This commit is contained in:
Benoit Blanchon
2020-07-22 20:38:09 +02:00
parent ebb6d80092
commit 40085609e2
3 changed files with 213 additions and 86 deletions

View File

@ -10,8 +10,11 @@
namespace ARDUINOJSON_NAMESPACE {
// Copy a 1D array to a JsonArray
template <typename T, size_t N>
inline bool copyArray(T (&src)[N], ArrayRef dst) {
template <typename T, size_t N, typename TDestination>
inline typename enable_if<!is_array<T>::value &&
!is_base_of<JsonDocument, TDestination>::value,
bool>::type
copyArray(T (&src)[N], const TDestination& dst) {
return copyArray(src, N, dst);
}
@ -22,8 +25,11 @@ inline bool copyArray(T (&src)[N], JsonDocument& dst) {
}
// Copy a 1D array to a JsonArray
template <typename T>
inline bool copyArray(T* src, size_t len, ArrayRef dst) {
template <typename T, typename TDestination>
inline typename enable_if<!is_array<T>::value &&
!is_base_of<JsonDocument, TDestination>::value,
bool>::type
copyArray(T* src, size_t len, const TDestination& dst) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= dst.add(src[i]);
@ -38,8 +44,10 @@ inline bool copyArray(T* src, size_t len, JsonDocument& dst) {
}
// Copy a 2D array to a JsonArray
template <typename T, size_t N1, size_t N2>
inline bool copyArray(T (&src)[N1][N2], ArrayRef dst) {
template <typename T, size_t N1, size_t N2, typename TDestination>
inline typename enable_if<!is_base_of<JsonDocument, TDestination>::value,
bool>::type
copyArray(T (&src)[N1][N2], const TDestination& dst) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
ArrayRef nestedArray = dst.createNestedArray();
@ -56,42 +64,87 @@ inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
return copyArray(src, dst.to<ArrayRef>());
}
template <typename T>
class ArrayCopier1D {
public:
ArrayCopier1D(T* destination, size_t capacity)
: _destination(destination), _capacity(capacity), _size(0) {}
void visitArray(const CollectionData& array) {
VariantSlot* slot = array.head();
while (slot != 0 && _size < _capacity) {
_destination[_size++] = variantAs<T>(slot->data());
slot = slot->next();
}
}
void visitObject(const CollectionData&) {}
void visitFloat(Float) {}
void visitString(const char*) {}
void visitRawJson(const char*, size_t) {}
void visitNegativeInteger(UInt) {}
void visitPositiveInteger(UInt) {}
void visitBoolean(bool) {}
void visitNull() {}
size_t result() const {
return _size;
}
private:
T* _destination;
size_t _capacity;
size_t _size;
};
template <typename T, size_t N1, size_t N2>
class ArrayCopier2D {
public:
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
void visitArray(const CollectionData& array) {
VariantSlot* slot = array.head();
size_t n = 0;
while (slot != 0 && n < N1) {
ArrayCopier1D<T> copier((*_destination)[n++], N2);
variantAccept(slot->data(), copier);
slot = slot->next();
}
}
void visitObject(const CollectionData&) {}
void visitFloat(Float) {}
void visitString(const char*) {}
void visitRawJson(const char*, size_t) {}
void visitNegativeInteger(UInt) {}
void visitPositiveInteger(UInt) {}
void visitBoolean(bool) {}
void visitNull() {}
private:
T (*_destination)[N1][N2];
size_t _capacity1, _capacity2;
};
// Copy a JsonArray to a 1D array
template <typename T, size_t N>
inline size_t copyArray(ArrayConstRef src, T (&dst)[N]) {
template <typename TSource, typename T, size_t N>
inline typename enable_if<!is_array<T>::value, size_t>::type copyArray(
const TSource& src, T (&dst)[N]) {
return copyArray(src, dst, N);
}
// Copy a JsonDocument to a 1D array
template <typename T, size_t N>
inline size_t copyArray(const JsonDocument& src, T (&dst)[N]) {
return copyArray(src.as<ArrayConstRef>(), dst, N);
}
// Copy a JsonArray to a 1D array
template <typename T>
inline size_t copyArray(ArrayConstRef src, T* dst, size_t len) {
size_t i = 0;
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < len;
++it)
dst[i++] = it->as<T>();
return i;
template <typename TSource, typename T>
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
ArrayCopier1D<T> copier(dst, len);
src.accept(copier);
return copier.result();
}
// Copy a JsonArray to a 2D array
template <typename T, size_t N1, size_t N2>
inline void copyArray(ArrayConstRef src, T (&dst)[N1][N2]) {
size_t i = 0;
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < N1;
++it) {
copyArray(it->as<ArrayConstRef>(), dst[i++]);
}
}
// Copy a JsonDocument to a 2D array
template <typename T, size_t N1, size_t N2>
inline void copyArray(const JsonDocument& src, T (&dst)[N1][N2]) {
copyArray(src.as<ArrayConstRef>(), dst);
template <typename TSource, typename T, size_t N1, size_t N2>
inline void copyArray(const TSource& src, T (&dst)[N1][N2]) {
ArrayCopier2D<T, N1, N2> copier(&dst);
src.accept(copier);
}
} // namespace ARDUINOJSON_NAMESPACE