Compare commits

...

7 Commits

21 changed files with 223 additions and 37 deletions

View File

@ -84,12 +84,12 @@ matrix:
env: SCRIPT=test _CC=clang-4.0 _CXX=clang++-4.0
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-5.0']
sources: ['ubuntu-toolchain-r-test']
packages: ['clang-5.0']
env: SCRIPT=test _CC=clang-5.0 _CXX=clang++-5.0
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
sources: ['ubuntu-toolchain-r-test']
packages: ['clang-6.0']
env: SCRIPT=test _CC=clang-6.0 _CXX=clang++-6.0
- addons:
@ -121,7 +121,7 @@ matrix:
- env: SCRIPT=platformio BOARD=esp01
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
sources: ['ubuntu-toolchain-r-test']
packages: ['clang-6.0','llvm-6.0']
env: SCRIPT=fuzz CLANG=6.0
cache:

View File

@ -1,6 +1,14 @@
ArduinoJson: change log
=======================
v6.11.4 (2019-08-12)
-------
* Added `measureJson()` to the `ArduinoJson` namespace (PR #1069 by @nomis)
* Added support for `basic_string<char, traits, allocator>` (issue #1045)
* Fixed example `JsonConfigFile.ino` for ESP8266
* Include `Arduino.h` if `ARDUINO` is defined (PR #1071 by @nomis)
v6.11.3 (2019-07-22)
-------

View File

@ -2,7 +2,7 @@
---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.11.3)](https://www.ardu-badge.com/ArduinoJson/6.11.3)
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.11.4)](https://www.ardu-badge.com/ArduinoJson/6.11.4)
[![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.3.{build}
version: 6.11.4.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017

View File

@ -11,6 +11,12 @@
// "port": 2731
// }
//
// To run this program, you need an SD card connected to the SPI bus as follows:
// * MOSI <-> pin 11
// * MISO <-> pin 12
// * CLK <-> pin 13
// * CS <-> pin 4
//
// https://arduinojson.org/v6/example/config/
#include <ArduinoJson.h>
@ -111,7 +117,8 @@ void setup() {
while (!Serial) continue;
// Initialize SD library
while (!SD.begin()) {
const int chipSelect = 4;
while (!SD.begin(chipSelect)) {
Serial.println(F("Failed to initialize SD library"));
delay(1000);
}

View File

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

View File

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

View File

@ -57,6 +57,7 @@ using ARDUINOJSON_NAMESPACE::deserializeJson;
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
using ARDUINOJSON_NAMESPACE::JsonDocument;
using ARDUINOJSON_NAMESPACE::measureJson;
using ARDUINOJSON_NAMESPACE::serialized;
using ARDUINOJSON_NAMESPACE::serializeJson;
using ARDUINOJSON_NAMESPACE::serializeJsonPretty;

View File

@ -90,6 +90,8 @@
#ifdef ARDUINO
#include <Arduino.h>
// Enable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
@ -107,17 +109,17 @@
#else // ARDUINO
// Enable support for Arduino's String class
// Disable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
// Enable support for Arduino's Stream class
// Disable support for Arduino's Stream class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
#endif
// Enable support for Arduino's Print class
// Disable support for Arduino's Print class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
#endif

View File

@ -10,19 +10,18 @@
#define ARDUINOJSON_DO_CONCAT(A, B) A##B
#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_DO_CONCAT(A, B)
#define ARDUINOJSON_CONCAT3(A, B, C) \
ARDUINOJSON_CONCAT2(A, ARDUINOJSON_CONCAT2(B, C))
#define ARDUINOJSON_CONCAT4(A, B, C, D) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D))
#define ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, H) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT4(A, B, C, D), \
ARDUINOJSON_CONCAT4(E, F, G, H))
#define ARDUINOJSON_CONCAT10(A, B, C, D, E, F, G, H, I, J) \
ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, ARDUINOJSON_CONCAT3(H, I, J))
#define ARDUINOJSON_CONCAT11(A, B, C, D, E, F, G, H, I, J, K) \
ARDUINOJSON_CONCAT8(A, B, C, D, E, F, G, ARDUINOJSON_CONCAT4(H, I, J, K))
#define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT10( \
ARDUINOJSON_CONCAT11( \
ArduinoJson, ARDUINOJSON_VERSION_MAJOR, ARDUINOJSON_VERSION_MINOR, \
ARDUINOJSON_VERSION_REVISION, _, ARDUINOJSON_USE_LONG_LONG, \
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE, \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY)
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_PROGMEM)

View File

@ -54,13 +54,16 @@ class DynamicStringWriter<String> {
#endif
#if ARDUINOJSON_ENABLE_STD_STRING
template <>
struct IsWriteableString<std::string> : true_type {};
template <typename TCharTraits, typename TAllocator>
struct IsWriteableString<std::basic_string<char, TCharTraits, TAllocator> >
: true_type {};
template <typename TCharTraits, typename TAllocator>
class DynamicStringWriter<std::basic_string<char, TCharTraits, TAllocator> > {
typedef std::basic_string<char, TCharTraits, TAllocator> string_type;
template <>
class DynamicStringWriter<std::string> {
public:
DynamicStringWriter(std::string &str) : _str(&str) {}
DynamicStringWriter(string_type &str) : _str(&str) {}
size_t write(uint8_t c) {
_str->operator+=(static_cast<char>(c));
@ -73,7 +76,7 @@ class DynamicStringWriter<std::string> {
}
private:
std::string *_str;
string_type *_str;
};
#endif
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -14,7 +14,7 @@ class FlashStringAdapter {
if (!other && !_str) return 0;
if (!_str) return -1;
if (!other) return 1;
return -strcmp_P(other, reinterpret_cast<const char*>(_str));
return int8_t(-strcmp_P(other, reinterpret_cast<const char*>(_str)));
}
bool equals(const char* expected) const {

View File

@ -15,7 +15,8 @@ class SizedFlashStringAdapter {
if (!other && !_str) return 0;
if (!_str) return -1;
if (!other) return 1;
return -strncmp_P(other, reinterpret_cast<const char*>(_str), _size);
return int8_t(
-strncmp_P(other, reinterpret_cast<const char*>(_str), _size));
}
bool equals(const char* expected) const {
@ -29,7 +30,7 @@ class SizedFlashStringAdapter {
char* save(MemoryPool* pool) const {
if (!_str) return NULL;
char* dup = pool->allocFrozenString(_size);
if (dup) memcpy_P(dup, (const char*)_str, _size);
if (dup) memcpy_P(dup, reinterpret_cast<const char*>(_str), _size);
return dup;
}

View File

@ -8,9 +8,10 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TString>
class StlStringAdapter {
public:
StlStringAdapter(const std::string& str) : _str(&str) {}
StlStringAdapter(const TString& str) : _str(&str) {}
char* save(MemoryPool* pool) const {
size_t n = _str->length() + 1;
@ -46,14 +47,18 @@ class StlStringAdapter {
}
private:
const std::string* _str;
const TString* _str;
};
template <>
struct IsString<std::string> : true_type {};
template <typename TCharTraits, typename TAllocator>
struct IsString<std::basic_string<char, TCharTraits, TAllocator> > : true_type {
};
inline StlStringAdapter adaptString(const std::string& str) {
return StlStringAdapter(str);
template <typename TCharTraits, typename TAllocator>
inline StlStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >
adaptString(const std::basic_string<char, TCharTraits, TAllocator>& str) {
return StlStringAdapter<std::basic_string<char, TCharTraits, TAllocator> >(
str);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

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

View File

@ -4,6 +4,7 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include "custom_string.hpp"
using namespace ARDUINOJSON_NAMESPACE;
@ -31,9 +32,9 @@ TEST_CASE("ConstRamStringAdapter") {
}
}
TEST_CASE("StlString") {
TEST_CASE("std::string") {
std::string str("bravo");
StlStringAdapter adapter(str);
StlStringAdapter<std::string> adapter = adaptString(str);
REQUIRE(adapter.compare(NULL) > 0);
REQUIRE(adapter.compare("alpha") > 0);
@ -43,3 +44,30 @@ TEST_CASE("StlString") {
REQUIRE(adapter.equals("bravo"));
REQUIRE_FALSE(adapter.equals("charlie"));
}
TEST_CASE("custom_string") {
custom_string str("bravo");
StlStringAdapter<custom_string> adapter = adaptString(str);
REQUIRE(adapter.compare(NULL) > 0);
REQUIRE(adapter.compare("alpha") > 0);
REQUIRE(adapter.compare("bravo") == 0);
REQUIRE(adapter.compare("charlie") < 0);
REQUIRE(adapter.equals("bravo"));
REQUIRE_FALSE(adapter.equals("charlie"));
}
TEST_CASE("IsString<T>") {
SECTION("std::string") {
REQUIRE(IsString<std::string>::value == true);
}
SECTION("basic_string<wchar_t>") {
REQUIRE(IsString<std::basic_string<wchar_t> >::value == false);
}
SECTION("custom_string") {
REQUIRE(IsString<custom_string>::value == true);
}
}

View File

@ -4,6 +4,7 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include "custom_string.hpp"
using namespace ARDUINOJSON_NAMESPACE;
@ -48,8 +49,30 @@ TEST_CASE("StaticStringWriter") {
}
}
TEST_CASE("DynamicStringWriter") {
TEST_CASE("DynamicStringWriter<std::string>") {
std::string output;
DynamicStringWriter<std::string> sb(output);
common_tests(sb, output);
}
TEST_CASE("DynamicStringWriter<custom_string>") {
custom_string output;
DynamicStringWriter<custom_string> sb(output);
REQUIRE(4 == print(sb, "ABCD"));
REQUIRE("ABCD" == output);
}
TEST_CASE("IsWriteableString") {
SECTION("std::string") {
REQUIRE(IsWriteableString<std::string>::value == true);
}
SECTION("custom_string") {
REQUIRE(IsWriteableString<custom_string>::value == true);
}
SECTION("basic_string<wchar_t>") {
REQUIRE(IsWriteableString<std::basic_string<wchar_t> >::value == false);
}
}

View File

@ -0,0 +1,14 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include <string>
using namespace ARDUINOJSON_NAMESPACE;
struct custom_char_traits : std::char_traits<char> {};
struct custom_allocator : std::allocator<char> {};
typedef std::basic_string<char, custom_char_traits, custom_allocator>
custom_string;

View File

@ -17,6 +17,7 @@ add_executable(MixedConfigurationTests
use_double_1.cpp
use_long_long_0.cpp
use_long_long_1.cpp
enable_progmem_1.cpp
)
target_link_libraries(MixedConfigurationTests catch)

View File

@ -0,0 +1,53 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include "progmem_emulation.hpp"
#define ARDUINOJSON_ENABLE_PROGMEM 1
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("Flash strings") {
DynamicJsonDocument doc(2048);
SECTION("deserializeJson()") {
DeserializationError err = deserializeJson(doc, F("{'hello':'world'}"));
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc["hello"] == "world");
}
SECTION("JsonDocument::operator[]") {
doc[F("hello")] = F("world");
REQUIRE(doc["hello"] == "world");
}
SECTION("JsonDocument::add()") {
doc.add(F("world"));
REQUIRE(doc[0] == "world");
}
SECTION("JsonVariant::set()") {
JsonVariant var = doc.to<JsonVariant>();
var.set(F("world"));
REQUIRE(var == "world");
}
SECTION("MemberProxy::operator==") {
doc["hello"] = "world";
REQUIRE(doc["hello"] == F("world"));
}
SECTION("ElementProxy::operator==") {
doc.add("world");
REQUIRE(doc[0] == F("world"));
}
}

View File

@ -0,0 +1,41 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <stdint.h> // uint8_t
#include <string.h> // strcmp, strlen...
class __FlashStringHelper;
typedef char prog_char;
typedef void prog_void;
inline const void* convertPtrToFlash(const void* s) {
return reinterpret_cast<const char*>(s) + 42;
}
inline const void* convertFlashToPtr(const void* s) {
return reinterpret_cast<const char*>(s) - 42;
}
#define F(X) reinterpret_cast<const __FlashStringHelper*>(convertPtrToFlash(X))
inline uint8_t pgm_read_byte_near(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)));
}