forked from bblanchon/ArduinoJson
Add pgm_ptr<T>
This commit is contained in:
@ -63,8 +63,8 @@ struct FloatParts {
|
|||||||
|
|
||||||
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
||||||
for (; index >= 0; index--) {
|
for (; index >= 0; index--) {
|
||||||
if (value >= traits::positiveBinaryPowerOfTen(index)) {
|
if (value >= traits::positiveBinaryPowersOfTen()[index]) {
|
||||||
value *= traits::negativeBinaryPowerOfTen(index);
|
value *= traits::negativeBinaryPowersOfTen()[index];
|
||||||
powersOf10 = int16_t(powersOf10 + bit);
|
powersOf10 = int16_t(powersOf10 + bit);
|
||||||
}
|
}
|
||||||
bit >>= 1;
|
bit >>= 1;
|
||||||
@ -73,8 +73,8 @@ struct FloatParts {
|
|||||||
|
|
||||||
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
||||||
for (; index >= 0; index--) {
|
for (; index >= 0; index--) {
|
||||||
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
|
if (value < traits::negativeBinaryPowersOfTenPlusOne()[index]) {
|
||||||
value *= traits::positiveBinaryPowerOfTen(index);
|
value *= traits::positiveBinaryPowersOfTen()[index];
|
||||||
powersOf10 = int16_t(powersOf10 - bit);
|
powersOf10 = int16_t(powersOf10 - bit);
|
||||||
}
|
}
|
||||||
bit >>= 1;
|
bit >>= 1;
|
||||||
|
@ -34,21 +34,21 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
|||||||
if (e > 0) {
|
if (e > 0) {
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
if (e & 1)
|
if (e & 1)
|
||||||
m *= positiveBinaryPowerOfTen(index);
|
m *= positiveBinaryPowersOfTen()[index];
|
||||||
e >>= 1;
|
e >>= 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e = TExponent(-e);
|
e = TExponent(-e);
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
if (e & 1)
|
if (e & 1)
|
||||||
m *= negativeBinaryPowerOfTen(index);
|
m *= negativeBinaryPowersOfTen()[index];
|
||||||
e >>= 1;
|
e >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T positiveBinaryPowerOfTen(int index) {
|
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
||||||
uint64_t, factors,
|
uint64_t, factors,
|
||||||
{
|
{
|
||||||
@ -62,10 +62,10 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
|||||||
0x5A827748F9301D32, // 1e128
|
0x5A827748F9301D32, // 1e128
|
||||||
0x75154FDD7F73BF3C, // 1e256
|
0x75154FDD7F73BF3C, // 1e256
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T negativeBinaryPowerOfTen(int index) {
|
static pgm_ptr<T> negativeBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
||||||
uint64_t, factors,
|
uint64_t, factors,
|
||||||
{
|
{
|
||||||
@ -79,10 +79,10 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
|||||||
0x255BBA08CF8C979D, // 1e-128
|
0x255BBA08CF8C979D, // 1e-128
|
||||||
0x0AC8062864AC6F43 // 1e-256
|
0x0AC8062864AC6F43 // 1e-256
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
static pgm_ptr<T> negativeBinaryPowersOfTenPlusOne() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY( //
|
||||||
uint64_t, factors,
|
uint64_t, factors,
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
|||||||
0x2591544581B7DEC2, // 1e-127
|
0x2591544581B7DEC2, // 1e-127
|
||||||
0x0AFE07B27DD78B14 // 1e-255
|
0x0AFE07B27DD78B14 // 1e-255
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T nan() {
|
static T nan() {
|
||||||
@ -154,21 +154,21 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
|||||||
if (e > 0) {
|
if (e > 0) {
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
if (e & 1)
|
if (e & 1)
|
||||||
m *= positiveBinaryPowerOfTen(index);
|
m *= positiveBinaryPowersOfTen()[index];
|
||||||
e >>= 1;
|
e >>= 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e = -e;
|
e = -e;
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
if (e & 1)
|
if (e & 1)
|
||||||
m *= negativeBinaryPowerOfTen(index);
|
m *= negativeBinaryPowersOfTen()[index];
|
||||||
e >>= 1;
|
e >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static T positiveBinaryPowerOfTen(int index) {
|
static pgm_ptr<T> positiveBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
||||||
{
|
{
|
||||||
0x41200000, // 1e1f
|
0x41200000, // 1e1f
|
||||||
@ -178,10 +178,10 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
|||||||
0x5a0e1bca, // 1e16f
|
0x5a0e1bca, // 1e16f
|
||||||
0x749dc5ae // 1e32f
|
0x749dc5ae // 1e32f
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T negativeBinaryPowerOfTen(int index) {
|
static pgm_ptr<T> negativeBinaryPowersOfTen() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
||||||
{
|
{
|
||||||
0x3dcccccd, // 1e-1f
|
0x3dcccccd, // 1e-1f
|
||||||
@ -191,10 +191,10 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
|||||||
0x24e69595, // 1e-16f
|
0x24e69595, // 1e-16f
|
||||||
0x0a4fb11f // 1e-32f
|
0x0a4fb11f // 1e-32f
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
static pgm_ptr<T> negativeBinaryPowersOfTenPlusOne() {
|
||||||
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
|
||||||
{
|
{
|
||||||
0x3f800000, // 1e0f
|
0x3f800000, // 1e0f
|
||||||
@ -204,7 +204,7 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
|||||||
0x26901d7d, // 1e-15f
|
0x26901d7d, // 1e-15f
|
||||||
0x0c01ceb3 // 1e-31f
|
0x0c01ceb3 // 1e-31f
|
||||||
});
|
});
|
||||||
return forge(pgm_read(factors + index));
|
return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
|
||||||
}
|
}
|
||||||
|
|
||||||
static T forge(uint32_t bits) {
|
static T forge(uint32_t bits) {
|
||||||
|
@ -106,6 +106,29 @@ inline uint32_t pgm_read_dword(ArduinoJson::detail::pgm_p p) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgm_read_float
|
||||||
|
inline float pgm_read_float(ArduinoJson::detail::pgm_p p) {
|
||||||
|
float result;
|
||||||
|
memcpy_P(&result, p.address, sizeof(float));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pgm_read_double
|
||||||
|
# if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_FLOAT__) && \
|
||||||
|
__SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__
|
||||||
|
inline double pgm_read_double(ArduinoJson::detail::pgm_p p) {
|
||||||
|
return pgm_read_float(p.address);
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
inline double pgm_read_double(ArduinoJson::detail::pgm_p p) {
|
||||||
|
double result;
|
||||||
|
memcpy_P(&result, p.address, sizeof(double));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef pgm_read_ptr
|
#ifndef pgm_read_ptr
|
||||||
inline void* pgm_read_ptr(ArduinoJson::detail::pgm_p p) {
|
inline void* pgm_read_ptr(ArduinoJson::detail::pgm_p p) {
|
||||||
void* result;
|
void* result;
|
||||||
|
@ -29,11 +29,12 @@ inline uint32_t pgm_read(const uint32_t* p) {
|
|||||||
return pgm_read_dword(p);
|
return pgm_read_dword(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
inline double pgm_read(const double* p) {
|
||||||
inline T pgm_read(const T* p) {
|
return pgm_read_double(p);
|
||||||
T result;
|
}
|
||||||
memcpy_P(&result, p, sizeof(T));
|
|
||||||
return result;
|
inline float pgm_read(const float* p) {
|
||||||
|
return pgm_read_float(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -50,4 +51,17 @@ inline T pgm_read(const T* p) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class pgm_ptr {
|
||||||
|
public:
|
||||||
|
explicit pgm_ptr(const T* ptr) : _ptr(ptr) {}
|
||||||
|
|
||||||
|
T operator[](intptr_t index) const {
|
||||||
|
return pgm_read(_ptr + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T* _ptr;
|
||||||
|
};
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user