Compare commits

..

2 Commits

11 changed files with 113 additions and 28 deletions

View File

@ -1,6 +1,11 @@
ArduinoJson: change log
=======================
v6.11.5 (2019-08-23)
-------
* Added fallback implementations of `strlen_P()`, `strncmp_P()`, `strcmp_P()`, and `memcpy_P()` (issue #1073)
v6.11.4 (2019-08-12)
-------

View File

@ -2,7 +2,7 @@
---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.11.4)](https://www.ardu-badge.com/ArduinoJson/6.11.4)
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.11.5)](https://www.ardu-badge.com/ArduinoJson/6.11.5)
[![Build Status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=6.x)](https://travis-ci.org/bblanchon/ArduinoJson)
[![Coverage Status](https://coveralls.io/repos/github/bblanchon/ArduinoJson/badge.svg?branch=6.x)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)

View File

@ -1,4 +1,4 @@
version: 6.11.4.{build}
version: 6.11.5.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017

View File

@ -7,7 +7,7 @@
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "6.11.4",
"version": "6.11.5",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"

View File

@ -1,5 +1,5 @@
name=ArduinoJson
version=6.11.4
version=6.11.5
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.

View File

@ -15,7 +15,7 @@ class UnsafeFlashStringReader {
: _ptr(reinterpret_cast<const char*>(ptr)) {}
int read() {
return pgm_read_byte_near(_ptr++);
return pgm_read_byte(_ptr++);
}
};
@ -29,7 +29,7 @@ class SafeFlashStringReader {
int read() {
if (_ptr < _end)
return pgm_read_byte_near(_ptr++);
return pgm_read_byte(_ptr++);
else
return -1;
}

View File

@ -0,0 +1,62 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
namespace ARDUINOJSON_NAMESPACE {
// Wraps a const char* so that the our functions are picked only if the
// originals are missing
struct pgm_p {
pgm_p(const char* p) : address(p) {}
const char* address;
};
} // namespace ARDUINOJSON_NAMESPACE
#ifndef strlen_P
inline size_t strlen_P(ARDUINOJSON_NAMESPACE::pgm_p s) {
const char* p = s.address;
while (pgm_read_byte(p)) p++;
return size_t(p - s.address);
}
#endif
#ifndef strncmp_P
inline int strncmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b, size_t n) {
const char* s1 = a;
const char* s2 = b.address;
while (n-- > 0) {
char c1 = *s1++;
char c2 = static_cast<char>(pgm_read_byte(s2++));
if (c1 < c2) return -1;
if (c1 > c2) return 1;
if (c1 == 0 /* and c2 as well */) return 0;
}
return 0;
}
#endif
#ifndef strcmp_P
inline int strcmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b) {
const char* s1 = a;
const char* s2 = b.address;
for (;;) {
char c1 = *s1++;
char c2 = static_cast<char>(pgm_read_byte(s2++));
if (c1 < c2) return -1;
if (c1 > c2) return 1;
if (c1 == 0 /* and c2 as well */) return 0;
}
}
#endif
#ifndef memcpy_P
inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
uint8_t* d = reinterpret_cast<uint8_t*>(dst);
const char* s = src.address;
while (n-- > 0) {
*d++ = pgm_read_byte(s++);
}
return dst;
}
#endif

View File

@ -4,6 +4,8 @@
#pragma once
#include "../Polyfills/pgmspace.hpp"
namespace ARDUINOJSON_NAMESPACE {
class FlashStringAdapter {

View File

@ -4,7 +4,7 @@
#pragma once
#define ARDUINOJSON_VERSION "6.11.4"
#define ARDUINOJSON_VERSION "6.11.5"
#define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 11
#define ARDUINOJSON_VERSION_REVISION 4
#define ARDUINOJSON_VERSION_REVISION 5

View File

@ -51,3 +51,37 @@ TEST_CASE("Flash strings") {
REQUIRE(doc[0] == F("world"));
}
}
TEST_CASE("strlen_P") {
CHECK(strlen_P(FC("")) == 0);
CHECK(strlen_P(FC("a")) == 1);
CHECK(strlen_P(FC("ac")) == 2);
}
TEST_CASE("strncmp_P") {
CHECK(strncmp_P("a", FC("b"), 0) == 0);
CHECK(strncmp_P("a", FC("b"), 1) == -1);
CHECK(strncmp_P("b", FC("a"), 1) == 1);
CHECK(strncmp_P("a", FC("a"), 0) == 0);
CHECK(strncmp_P("a", FC("b"), 2) == -1);
CHECK(strncmp_P("b", FC("a"), 2) == 1);
CHECK(strncmp_P("a", FC("a"), 2) == 0);
}
TEST_CASE("strcmp_P") {
CHECK(strcmp_P("a", FC("b")) == -1);
CHECK(strcmp_P("b", FC("a")) == 1);
CHECK(strcmp_P("a", FC("a")) == 0);
CHECK(strcmp_P("aa", FC("ab")) == -1);
CHECK(strcmp_P("ab", FC("aa")) == 1);
CHECK(strcmp_P("aa", FC("aa")) == 0);
}
TEST_CASE("memcpy_P") {
char dst[4];
CHECK(memcpy_P(dst, FC("ABC"), 4) == dst);
CHECK(dst[0] == 'A');
CHECK(dst[1] == 'B');
CHECK(dst[2] == 'C');
CHECK(dst[3] == 0);
}

View File

@ -7,9 +7,6 @@
class __FlashStringHelper;
typedef char prog_char;
typedef void prog_void;
inline const void* convertPtrToFlash(const void* s) {
return reinterpret_cast<const char*>(s) + 42;
}
@ -19,23 +16,8 @@ inline const void* convertFlashToPtr(const void* s) {
}
#define F(X) reinterpret_cast<const __FlashStringHelper*>(convertPtrToFlash(X))
#define FC(X) reinterpret_cast<const char*>(convertPtrToFlash(X))
inline uint8_t pgm_read_byte_near(const void* p) {
inline uint8_t pgm_read_byte(const void* p) {
return *reinterpret_cast<const uint8_t*>(convertFlashToPtr(p));
}
inline void* memcpy_P(void* a, const prog_void* b, size_t n) {
return memcpy(a, convertFlashToPtr(b), n);
}
inline int strcmp_P(const char* a, const prog_char* b) {
return strcmp(a, reinterpret_cast<const char*>(convertFlashToPtr(b)));
}
inline int strncmp_P(const char* a, const prog_char* b, size_t n) {
return strncmp(a, reinterpret_cast<const char*>(convertFlashToPtr(b)), n);
}
inline size_t strlen_P(const prog_char* s) {
return strlen(reinterpret_cast<const char*>(convertFlashToPtr(s)));
}