mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-03 13:46:46 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
f5c25823bc | |||
f00dfd7bfe | |||
dcca4214f5 | |||
1e9cc285bb | |||
b9c4a0c5f6 | |||
0d339300f9 | |||
63d7d87080 | |||
2ee655f9ba | |||
61a4195ed4 | |||
a6f029ded0 | |||
b54de58e6b | |||
795e37278f | |||
7ce1039d7c | |||
aba42faf69 |
@ -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:
|
||||
|
19
CHANGELOG.md
19
CHANGELOG.md
@ -1,6 +1,25 @@
|
||||
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)
|
||||
-------
|
||||
|
||||
* 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)
|
||||
-------
|
||||
|
||||
* Added operators `==` and `!=` for `JsonDocument`, `ElementProxy`, and `MemberProxy`
|
||||
* Fixed comparison of `JsonVariant` when one contains a linked string and the other contains an owned string (issue #1051)
|
||||
|
||||
v6.11.2 (2019-07-08)
|
||||
-------
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
---
|
||||
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.11.2)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.11.5)
|
||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 6.11.2.{build}
|
||||
version: 6.11.5.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "6.11.2",
|
||||
"version": "6.11.5",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=6.11.2
|
||||
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.
|
||||
|
@ -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;
|
||||
|
@ -47,6 +47,14 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamElement()) == rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator!=(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamElement()) != rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamElement().clear();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -282,6 +282,14 @@ class JsonDocument : public Visitable {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
bool operator==(VariantConstRef rhs) const {
|
||||
return getVariant() == rhs;
|
||||
}
|
||||
|
||||
bool operator!=(VariantConstRef rhs) const {
|
||||
return getVariant() != rhs;
|
||||
}
|
||||
|
||||
protected:
|
||||
JsonDocument(MemoryPool pool) : _pool(pool) {
|
||||
_data.setNull();
|
||||
|
@ -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)
|
||||
|
@ -49,6 +49,14 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamMember()) == rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator!=(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamMember()) != rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamMember().clear();
|
||||
}
|
||||
|
@ -126,7 +126,8 @@ class VariantComparisons {
|
||||
return compare(rhs, lhs) == 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend bool operator==(const T &lhs, TVariant rhs) {
|
||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
||||
const T &lhs, TVariant rhs) {
|
||||
return compare(rhs, lhs) == 0;
|
||||
}
|
||||
|
||||
@ -136,7 +137,8 @@ class VariantComparisons {
|
||||
return compare(lhs, rhs) == 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend bool operator==(TVariant lhs, const T &rhs) {
|
||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator==(
|
||||
TVariant lhs, const T &rhs) {
|
||||
return compare(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
@ -146,7 +148,8 @@ class VariantComparisons {
|
||||
return compare(rhs, lhs) != 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend bool operator!=(const T &lhs, TVariant rhs) {
|
||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
||||
const T &lhs, TVariant rhs) {
|
||||
return compare(rhs, lhs) != 0;
|
||||
}
|
||||
|
||||
@ -156,7 +159,8 @@ class VariantComparisons {
|
||||
return compare(lhs, rhs) != 0;
|
||||
}
|
||||
template <typename T>
|
||||
friend bool operator!=(TVariant lhs, const T &rhs) {
|
||||
friend typename enable_if<!IsVisitable<T>::value, bool>::type operator!=(
|
||||
TVariant lhs, const T &rhs) {
|
||||
return compare(lhs, rhs) != 0;
|
||||
}
|
||||
|
||||
|
62
src/ArduinoJson/Polyfills/pgmspace.hpp
Normal file
62
src/ArduinoJson/Polyfills/pgmspace.hpp
Normal 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
|
@ -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
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/pgmspace.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class FlashStringAdapter {
|
||||
@ -14,7 +16,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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -16,15 +16,18 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
enum {
|
||||
VALUE_MASK = 0x7F,
|
||||
|
||||
OWNERSHIP_BIT = 0x01,
|
||||
VALUE_IS_NULL = 0,
|
||||
VALUE_IS_LINKED_RAW = 0x01,
|
||||
VALUE_IS_OWNED_RAW = 0x02,
|
||||
VALUE_IS_LINKED_STRING = 0x03,
|
||||
VALUE_IS_OWNED_STRING = 0x04,
|
||||
VALUE_IS_BOOLEAN = 0x05,
|
||||
VALUE_IS_POSITIVE_INTEGER = 0x06,
|
||||
VALUE_IS_NEGATIVE_INTEGER = 0x07,
|
||||
VALUE_IS_FLOAT = 0x08,
|
||||
VALUE_IS_LINKED_RAW = 0x02,
|
||||
VALUE_IS_OWNED_RAW = 0x03,
|
||||
VALUE_IS_LINKED_STRING = 0x04,
|
||||
VALUE_IS_OWNED_STRING = 0x05,
|
||||
|
||||
// CAUTION: no OWNERSHIP_BIT below
|
||||
VALUE_IS_BOOLEAN = 0x06,
|
||||
VALUE_IS_POSITIVE_INTEGER = 0x08,
|
||||
VALUE_IS_NEGATIVE_INTEGER = 0x0A,
|
||||
VALUE_IS_FLOAT = 0x0C,
|
||||
|
||||
COLLECTION_MASK = 0x60,
|
||||
VALUE_IS_OBJECT = 0x20,
|
||||
|
@ -101,7 +101,9 @@ class VariantData {
|
||||
}
|
||||
|
||||
bool equals(const VariantData &other) const {
|
||||
if (type() != other.type()) return false;
|
||||
// Check that variant have the same type, but ignore string ownership
|
||||
if ((type() | OWNERSHIP_BIT) != (other.type() | OWNERSHIP_BIT))
|
||||
return false;
|
||||
|
||||
switch (type()) {
|
||||
case VALUE_IS_LINKED_STRING:
|
||||
|
@ -380,5 +380,13 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
const CollectionData *obj = variantAsObject(_data);
|
||||
return VariantConstRef(obj ? obj->get(adaptString(key)) : 0);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(VariantConstRef lhs) const {
|
||||
return variantEquals(_data, lhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator!=(VariantConstRef lhs) const {
|
||||
return !variantEquals(_data, lhs._data);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARDUINOJSON_VERSION "6.11.2"
|
||||
#define ARDUINOJSON_VERSION "6.11.5"
|
||||
#define ARDUINOJSON_VERSION_MAJOR 6
|
||||
#define ARDUINOJSON_VERSION_MINOR 11
|
||||
#define ARDUINOJSON_VERSION_REVISION 2
|
||||
#define ARDUINOJSON_VERSION_REVISION 5
|
||||
|
@ -5,6 +5,7 @@
|
||||
add_executable(ElementProxyTests
|
||||
add.cpp
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
remove.cpp
|
||||
set.cpp
|
||||
size.cpp
|
||||
|
28
test/ElementProxy/compare.cpp
Normal file
28
test/ElementProxy/compare.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
|
||||
TEST_CASE("ElementProxy::operator==()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("same value") {
|
||||
doc.add(1);
|
||||
doc.add(1);
|
||||
|
||||
REQUIRE(doc[0] == doc[1]);
|
||||
REQUIRE_FALSE(doc[0] != doc[1]);
|
||||
}
|
||||
|
||||
SECTION("different values") {
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
|
||||
REQUIRE_FALSE(doc[0] == doc[1]);
|
||||
REQUIRE(doc[0] != doc[1]);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
add_executable(JsonDocumentTests
|
||||
add.cpp
|
||||
BasicJsonDocument.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
createNested.cpp
|
||||
DynamicJsonDocument.cpp
|
||||
|
77
test/JsonDocument/compare.cpp
Normal file
77
test/JsonDocument/compare.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("DynamicJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
DynamicJsonDocument doc2(4096);
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument::operator==(const StaticJsonDocument&)") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
StaticJsonDocument<256> doc2;
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
StaticJsonDocument<256> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
@ -286,6 +286,17 @@ TEST_CASE("JsonVariant comparisons") {
|
||||
REQUIRE_FALSE(variant1 == variant3);
|
||||
}
|
||||
|
||||
SECTION("Variants containing mixed strings (issue #1051)") {
|
||||
variant1.set("hello");
|
||||
variant2.set(std::string("hello"));
|
||||
|
||||
REQUIRE(variant1 == variant2);
|
||||
REQUIRE_FALSE(variant1 != variant2);
|
||||
|
||||
REQUIRE(variant2 == variant1);
|
||||
REQUIRE_FALSE(variant2 != variant1);
|
||||
}
|
||||
|
||||
SECTION("Variants containing double") {
|
||||
variant1.set(42.0);
|
||||
variant2.set(42.0);
|
||||
|
@ -5,6 +5,7 @@
|
||||
add_executable(MemberProxyTests
|
||||
add.cpp
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
remove.cpp
|
||||
set.cpp
|
||||
|
26
test/MemberProxy/compare.cpp
Normal file
26
test/MemberProxy/compare.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ARDUINOJSON_NAMESPACE;
|
||||
|
||||
TEST_CASE("MemberProxy::operator==()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("same values") {
|
||||
doc["key1"] = "value";
|
||||
doc["key2"] = "value";
|
||||
REQUIRE(doc["key1"] == doc["key2"]);
|
||||
REQUIRE_FALSE(doc["key1"] != doc["key2"]);
|
||||
}
|
||||
|
||||
SECTION("different values") {
|
||||
doc["key1"] = "value1";
|
||||
doc["key2"] = "value2";
|
||||
REQUIRE_FALSE(doc["key1"] == doc["key2"]);
|
||||
REQUIRE(doc["key1"] != doc["key2"]);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
14
test/Misc/custom_string.hpp
Normal file
14
test/Misc/custom_string.hpp
Normal 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;
|
@ -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)
|
||||
|
87
test/MixedConfiguration/enable_progmem_1.cpp
Normal file
87
test/MixedConfiguration/enable_progmem_1.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
// 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"));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
23
test/MixedConfiguration/progmem_emulation.hpp
Normal file
23
test/MixedConfiguration/progmem_emulation.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#include <stdint.h> // uint8_t
|
||||
#include <string.h> // strcmp, strlen...
|
||||
|
||||
class __FlashStringHelper;
|
||||
|
||||
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))
|
||||
#define FC(X) reinterpret_cast<const char*>(convertPtrToFlash(X))
|
||||
|
||||
inline uint8_t pgm_read_byte(const void* p) {
|
||||
return *reinterpret_cast<const uint8_t*>(convertFlashToPtr(p));
|
||||
}
|
Reference in New Issue
Block a user