Skip to content

Commit 029b3c5

Browse files
committed
Add pgm_array<T, N> as a bound-safe alternative to pgm_ptr<T>
See #2220
1 parent a9bb1a1 commit 029b3c5

3 files changed

Lines changed: 31 additions & 12 deletions

File tree

src/ArduinoJson/Numbers/FloatParts.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ inline int16_t normalize(TFloat& value) {
2828

2929
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
3030
for (; index >= 0; index--) {
31-
if (value >= traits::positiveBinaryPowersOfTen()[index]) {
32-
value *= traits::negativeBinaryPowersOfTen()[index];
31+
if (value >= traits::positiveBinaryPowersOfTen()[uint8_t(index)]) {
32+
value *= traits::negativeBinaryPowersOfTen()[uint8_t(index)];
3333
powersOf10 = int16_t(powersOf10 + bit);
3434
}
3535
bit >>= 1;
@@ -38,8 +38,8 @@ inline int16_t normalize(TFloat& value) {
3838

3939
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
4040
for (; index >= 0; index--) {
41-
if (value < traits::negativeBinaryPowersOfTen()[index] * 10) {
42-
value *= traits::positiveBinaryPowersOfTen()[index];
41+
if (value < traits::negativeBinaryPowersOfTen()[uint8_t(index)] * 10) {
42+
value *= traits::positiveBinaryPowersOfTen()[uint8_t(index)];
4343
powersOf10 = int16_t(powersOf10 - bit);
4444
}
4545
bit >>= 1;

src/ArduinoJson/Numbers/FloatTraits.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct FloatTraits<T, 8 /*64bits*/> {
2929
using exponent_type = int16_t;
3030
static const exponent_type exponent_max = 308;
3131

32-
static pgm_ptr<T> positiveBinaryPowersOfTen() {
32+
static pgm_array<T, 9> positiveBinaryPowersOfTen() {
3333
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
3434
uint64_t, factors,
3535
{
@@ -43,10 +43,10 @@ struct FloatTraits<T, 8 /*64bits*/> {
4343
0x5A827748F9301D32, // 1e128
4444
0x75154FDD7F73BF3C, // 1e256
4545
});
46-
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
46+
return pgm_array<T, 9>(reinterpret_cast<const T*>(factors));
4747
}
4848

49-
static pgm_ptr<T> negativeBinaryPowersOfTen() {
49+
static pgm_array<T, 9> negativeBinaryPowersOfTen() {
5050
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
5151
uint64_t, factors,
5252
{
@@ -60,7 +60,7 @@ struct FloatTraits<T, 8 /*64bits*/> {
6060
0x255BBA08CF8C979D, // 1e-128
6161
0x0AC8062864AC6F43 // 1e-256
6262
});
63-
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
63+
return pgm_array<T, 9>(reinterpret_cast<const T*>(factors));
6464
}
6565

6666
static T nan() {
@@ -113,7 +113,7 @@ struct FloatTraits<T, 4 /*32bits*/> {
113113
using exponent_type = int8_t;
114114
static const exponent_type exponent_max = 38;
115115

116-
static pgm_ptr<T> positiveBinaryPowersOfTen() {
116+
static pgm_array<T, 6> positiveBinaryPowersOfTen() {
117117
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
118118
{
119119
0x41200000, // 1e1f
@@ -123,10 +123,10 @@ struct FloatTraits<T, 4 /*32bits*/> {
123123
0x5a0e1bca, // 1e16f
124124
0x749dc5ae // 1e32f
125125
});
126-
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
126+
return pgm_array<T, 6>(reinterpret_cast<const T*>(factors));
127127
}
128128

129-
static pgm_ptr<T> negativeBinaryPowersOfTen() {
129+
static pgm_array<T, 6> negativeBinaryPowersOfTen() {
130130
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
131131
{
132132
0x3dcccccd, // 1e-1f
@@ -136,7 +136,7 @@ struct FloatTraits<T, 4 /*32bits*/> {
136136
0x24e69595, // 1e-16f
137137
0x0a4fb11f // 1e-32f
138138
});
139-
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
139+
return pgm_array<T, 6>(reinterpret_cast<const T*>(factors));
140140
}
141141

142142
static T forge(uint32_t bits) {

src/ArduinoJson/Polyfills/pgmspace_generic.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include <ArduinoJson/Namespace.hpp>
8+
#include <ArduinoJson/Polyfills/assert.hpp>
89

910
#if ARDUINOJSON_ENABLE_PROGMEM
1011
# include <ArduinoJson/Polyfills/pgmspace.hpp>
@@ -64,4 +65,22 @@ class pgm_ptr {
6465
const T* ptr_;
6566
};
6667

68+
template <typename T, size_t N>
69+
class pgm_array {
70+
public:
71+
explicit pgm_array(const T* ptr) : ptr_(ptr) {}
72+
73+
T operator[](size_t index) const {
74+
ARDUINOJSON_ASSERT(index < N);
75+
return ptr_[intptr_t(index)];
76+
}
77+
78+
size_t size() const {
79+
return N;
80+
}
81+
82+
private:
83+
pgm_ptr<T> ptr_;
84+
};
85+
6786
ARDUINOJSON_END_PRIVATE_NAMESPACE

0 commit comments

Comments
 (0)