Преглед изворни кода

Allowed more than 32767 values in non-embedded mode (fixes #1414)

Benoit Blanchon пре 5 година
родитељ
комит
c711fe592d

+ 1 - 0
CHANGELOG.md

@@ -6,6 +6,7 @@ HEAD
 
 * Fixed error `ambiguous overload for 'operator|'` (issue #1411)
 * Fixed `operator|(MemberProxy, JsonObject)` (issue #1415)
+* Allowed more than 32767 values in non-embedded mode (issue #1414)
 
 v6.17.0 (2020-10-19)
 -------

+ 17 - 0
src/ArduinoJson/Configuration.hpp

@@ -83,6 +83,18 @@
 #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
 #endif
 
+// Number of bits to store the pointer to next node
+// (saves RAM but limits the number of values in a document)
+#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
+#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 2
+// Address space == 16-bit => max 127 values
+#define ARDUINOJSON_SLOT_OFFSET_SIZE 1
+#else
+// Address space > 16-bit => max 32767 values
+#define ARDUINOJSON_SLOT_OFFSET_SIZE 2
+#endif
+#endif
+
 #else  // ARDUINOJSON_EMBEDDED_MODE
 
 // On a computer we have plenty of memory so we can use doubles
@@ -114,6 +126,11 @@
 #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
 #endif
 
+// Number of bits to store the pointer to next node
+#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
+#define ARDUINOJSON_SLOT_OFFSET_SIZE 4
+#endif
+
 #endif  // ARDUINOJSON_EMBEDDED_MODE
 
 #ifdef ARDUINO

+ 30 - 0
src/ArduinoJson/Polyfills/integer.hpp

@@ -0,0 +1,30 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2020
+// MIT License
+
+#pragma once
+
+#include <stdint.h>  // int8_t, int16_t
+
+#include <ArduinoJson/Namespace.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <int Bits>
+struct int_t;
+
+template <>
+struct int_t<8> {
+  typedef int8_t type;
+};
+
+template <>
+struct int_t<16> {
+  typedef int16_t type;
+};
+
+template <>
+struct int_t<32> {
+  typedef int32_t type;
+};
+}  // namespace ARDUINOJSON_NAMESPACE

+ 4 - 5
src/ArduinoJson/Variant/VariantSlot.hpp

@@ -4,8 +4,7 @@
 
 #pragma once
 
-#include <stdint.h>  // int8_t, int16_t
-
+#include <ArduinoJson/Polyfills/integer.hpp>
 #include <ArduinoJson/Polyfills/limits.hpp>
 #include <ArduinoJson/Polyfills/type_traits.hpp>
 #include <ArduinoJson/Strings/StoragePolicy.hpp>
@@ -13,7 +12,7 @@
 
 namespace ARDUINOJSON_NAMESPACE {
 
-typedef conditional<sizeof(void*) <= 2, int8_t, int16_t>::type VariantSlotDiff;
+typedef int_t<ARDUINOJSON_SLOT_OFFSET_SIZE * 8>::type VariantSlotDiff;
 
 class VariantSlot {
   // CAUTION: same layout as VariantData
@@ -63,9 +62,9 @@ class VariantSlot {
 
   void setNext(VariantSlot* slot) {
     ARDUINOJSON_ASSERT(!slot || slot - this >=
-                       numeric_limits<VariantSlotDiff>::lowest());
+                                    numeric_limits<VariantSlotDiff>::lowest());
     ARDUINOJSON_ASSERT(!slot || slot - this <=
-                       numeric_limits<VariantSlotDiff>::highest());
+                                    numeric_limits<VariantSlotDiff>::highest());
     _next = VariantSlotDiff(slot ? slot - this : 0);
   }