Exchanged read/write of performance data to JSON format.

Added latest ArduinoJSON library to third-Party software.
pull/54/head
Holger Wirtz 3 years ago
parent 1e53e14416
commit f458bbb8c1
  1. 8
      UI.hpp
  2. 2
      config.h
  3. 141
      dexed_sd.cpp
  4. 6
      dexed_sd.h
  5. 7
      drums.h
  6. 6
      third-party/ArduinoJson/CHANGELOG.md
  7. 2
      third-party/ArduinoJson/CMakeLists.txt
  8. 2
      third-party/ArduinoJson/README.md
  9. 2
      third-party/ArduinoJson/appveyor.yml
  10. 4
      third-party/ArduinoJson/extras/scripts/get-release-page.sh
  11. 2
      third-party/ArduinoJson/extras/scripts/publish.sh
  12. 18
      third-party/ArduinoJson/extras/tests/Cpp17/string_view.cpp
  13. 6
      third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp
  14. 60
      third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp
  15. 2
      third-party/ArduinoJson/library.json
  16. 2
      third-party/ArduinoJson/library.properties
  17. 8
      third-party/ArduinoJson/src/ArduinoJson/Array/ArrayRef.hpp
  18. 4
      third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp
  19. 6
      third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp
  20. 4
      third-party/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp
  21. 2
      third-party/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp
  22. 4
      third-party/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp
  23. 8
      third-party/ArduinoJson/src/ArduinoJson/Object/ObjectRef.hpp
  24. 1
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/type_traits.hpp
  25. 14
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/make_void.hpp
  26. 52
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp
  27. 51
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp
  28. 48
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp
  29. 27
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/JsonStringAdapter.hpp
  30. 29
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/RamStringAdapter.hpp
  31. 48
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp
  32. 43
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp
  33. 46
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/StdStringAdapter.hpp
  34. 44
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/StringViewAdapter.hpp
  35. 25
      third-party/ArduinoJson/src/ArduinoJson/Strings/String.hpp
  36. 32
      third-party/ArduinoJson/src/ArduinoJson/Strings/StringAdapter.hpp
  37. 17
      third-party/ArduinoJson/src/ArduinoJson/Strings/StringAdapters.hpp
  38. 65
      third-party/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp
  39. 2
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp
  40. 5
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantData.hpp
  41. 14
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantRef.hpp
  42. 4
      third-party/ArduinoJson/src/ArduinoJson/version.hpp

@ -4475,7 +4475,7 @@ void UI_func_load_performance(uint8_t param)
mode = 0xff; mode = 0xff;
lcd.setCursor(0, 1); lcd.setCursor(0, 1);
if (load_sd_performance(configuration.sys.performance_number) == false) if (load_sd_performance_json(configuration.sys.performance_number) == false)
lcd.print("Does not exist."); lcd.print("Does not exist.");
else else
{ {
@ -4580,10 +4580,10 @@ void UI_func_save_performance(uint8_t param)
if (yesno == true) if (yesno == true)
{ {
char tmp[FILENAME_LEN]; char tmp[FILENAME_LEN];
sprintf(tmp, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); sprintf(tmp, "/%s/%s%d.json", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number);
SD.remove(tmp); SD.remove(tmp);
} }
save_sd_performance(configuration.sys.performance_number); save_sd_performance_json(configuration.sys.performance_number);
lcd.show(1, 0, 16, "Done."); lcd.show(1, 0, 16, "Done.");
delay(MESSAGE_WAIT_TIME); delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu(); LCDML.FUNC_goBackToMenu();
@ -4603,7 +4603,7 @@ void UI_func_save_performance(uint8_t param)
if (mode == 0) if (mode == 0)
{ {
char tmp[FILENAME_LEN]; char tmp[FILENAME_LEN];
sprintf(tmp, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); sprintf(tmp, "/%s/%s%d.json", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number);
if (SD.exists(tmp)) if (SD.exists(tmp))
overwrite = true; overwrite = true;
else else

@ -278,7 +278,7 @@
#define MAX_PERFORMANCE 99 #define MAX_PERFORMANCE 99
#define MAX_VOICECONFIG 99 #define MAX_VOICECONFIG 99
#define BANK_NAME_LEN 11 // 10 (plus '\0') #define BANK_NAME_LEN 11 // 10 (plus '\0')
#define VOICE_NAME_LEN 11 // 10 (plus '\0') #define VOICE_NAME_LEN 12 // 11 (plus '\0')
#define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN #define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN
#define FX_CONFIG_PATH "FXCFG" #define FX_CONFIG_PATH "FXCFG"

@ -715,19 +715,146 @@ bool save_sd_performance(uint8_t p)
return (false); return (false);
} }
/****************************************************************************** bool load_sd_performance_json(int8_t p)
HELPER FUNCTIONS
******************************************************************************/
bool get_sd_data_json(File sysex, uint8_t* conf)
{ {
return(false); if (p < 0)
return (false);
p = constrain(p, 0, MAX_PERFORMANCE);
if (sd_card > 0)
{
File json;
char filename[FILENAME_LEN];
sprintf(filename, "/%s/%s%d.json", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, p);
// first check if file exists...
AudioNoInterrupts();
if (SD.exists(filename))
{
// ... and if: load
#ifdef DEBUG
Serial.print(F("Found performance configuration ["));
Serial.print(filename);
Serial.println(F("]... loading..."));
#endif
json = SD.open(filename);
if (json)
{
StaticJsonDocument<256> data_json;
deserializeJson(data_json, json);
#ifdef DEBUG
Serial.println(F("Read JSON data:"));
serializeJsonPretty(data_json, Serial);
Serial.println();
#endif
for (uint8_t i = 0; i < MAX_DEXED; i++)
{
configuration.performance.bank[i] = data_json["bank"][i];
configuration.performance.voice[i] = data_json["voice"][i];
configuration.performance.voiceconfig_number[i] = data_json["voiceconfig_number"][i];
}
configuration.performance.fx_number = data_json["fx_number"];
json.close();
AudioInterrupts();
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{
load_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id);
MicroDexed[instance_id]->ControllersRefresh();
MicroDexed[instance_id]->panic();
}
load_sd_fx(configuration.performance.fx_number);
return (true);
}
#ifdef DEBUG
else
{
Serial.print(F("E : Cannot open "));
Serial.print(filename);
Serial.println(F(" on SD."));
}
#endif
}
else
{
#ifdef DEBUG
Serial.print(F("No "));
Serial.print(filename);
Serial.println(F(" available."));
#endif
}
}
return (false);
} }
bool write_sd_data_json(File sysex, uint16_t len) bool save_sd_performance_json(uint8_t p)
{ {
return(false); char filename[FILENAME_LEN];
p = constrain(p, 0, MAX_PERFORMANCE);
if (sd_card > 0)
{
File json;
sprintf(filename, "/%s/%s%d.json", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, p);
#ifdef DEBUG
Serial.print(F("Saving performance config as JSON"));
Serial.print(p);
Serial.print(F(" to "));
Serial.println(filename);
#endif
AudioNoInterrupts();
json = SD.open(filename, FILE_WRITE);
if (json)
{
StaticJsonDocument<256> data_json;
for (uint8_t i = 0; i < MAX_DEXED; i++)
{
data_json["bank"][i] = configuration.performance.bank[i];
data_json["voice"][i] = configuration.performance.voice[i];
data_json["voiceconfig_number"][i] = configuration.performance.voiceconfig_number[i];
}
data_json["fx_number"] = configuration.performance.fx_number;
#ifdef DEBUG
Serial.println(F("Write JSON data:"));
serializeJsonPretty(data_json, Serial);
Serial.println();
#endif
serializeJsonPretty(data_json, json);
json.close();
AudioInterrupts();
return (true);
}
json.close();
}
else
{
#ifdef DEBUG
Serial.print(F("E : Cannot open "));
Serial.print(filename);
Serial.println(F(" on SD."));
#endif
}
AudioInterrupts();
return (false);
} }
/******************************************************************************
HELPER FUNCTIONS
******************************************************************************/
bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) bool get_sd_data(File sysex, uint8_t format, uint8_t* conf)
{ {
uint16_t n; uint16_t n;

@ -62,11 +62,13 @@ bool save_sd_fx(uint8_t fx);
bool load_sd_performance(int8_t p); bool load_sd_performance(int8_t p);
bool save_sd_performance(uint8_t p); bool save_sd_performance(uint8_t p);
bool load_sd_performance_json(int8_t p);
bool save_sd_performance_json(uint8_t p);
bool get_sd_data_json(File sysex, uint8_t* conf);
bool write_sd_data_json(File sysex, uint8_t* data, uint16_t len);
bool get_sd_data(File sysex, uint8_t format, uint8_t* conf); bool get_sd_data(File sysex, uint8_t format, uint8_t* conf);
bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len); bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len);
uint8_t calc_checksum(uint8_t* data, uint16_t len); uint8_t calc_checksum(uint8_t* data, uint16_t len);
void strip_extension(const char* s, char* target); void strip_extension(const char* s, char* target);

@ -1,5 +1,10 @@
/* /*
Copyright (c) 2019-2021 H. Wirtz MicroDexed
MicroDexed is a port of the Dexed sound engine
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
(c)2018-2021 H. Wirtz <wirtz@parasitstudio.de>
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

@ -1,6 +1,12 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
v6.18.3 (2021-07-27)
-------
* Changed return type of `convertToJson()` and `Converter<T>::toJson()` to `void`
* Added `as<std::string_view>()` and `is<std::string_view>()`
v6.18.2 (2021-07-19) v6.18.2 (2021-07-19)
------- -------

@ -11,7 +11,7 @@ if(ESP_PLATFORM)
return() return()
endif() endif()
project(ArduinoJson VERSION 6.18.2) project(ArduinoJson VERSION 6.18.3)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest) include(CTest)

@ -2,7 +2,7 @@
--- ---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.18.2)](https://www.ardu-badge.com/ArduinoJson/6.18.2) [![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.18.3)](https://www.ardu-badge.com/ArduinoJson/6.18.3)
[![Continuous Integration](https://github.com/bblanchon/ArduinoJson/workflows/Continuous%20Integration/badge.svg?branch=6.x)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x) [![Continuous Integration](https://github.com/bblanchon/ArduinoJson/workflows/Continuous%20Integration/badge.svg?branch=6.x)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) [![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)

@ -1,4 +1,4 @@
version: 6.18.2.{build} version: 6.18.3.{build}
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019

@ -2,14 +2,14 @@
set -eu set -eu
TAG="$1" VERSION="$1"
CHANGELOG="$2" CHANGELOG="$2"
FRONTMATTER="$3" FRONTMATTER="$3"
cat << END cat << END
--- ---
branch: v6 branch: v6
version: $TAG version: $VERSION
date: '$(date +'%Y-%m-%d')' date: '$(date +'%Y-%m-%d')'
$(cat "$FRONTMATTER") $(cat "$FRONTMATTER")
--- ---

@ -63,6 +63,6 @@ extras/scripts/build-arduino-package.sh . "../ArduinoJson-$TAG.zip"
extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h" extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h"
extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp" extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp"
extras/scripts/wandbox/publish.sh "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG-wandbox.txt" extras/scripts/wandbox/publish.sh "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG-wandbox.txt"
extras/scripts/get-release-page.sh "$TAG" "CHANGELOG.md" "../ArduinoJson-$TAG-wandbox.txt" > "../ArduinoJson-$TAG.md" extras/scripts/get-release-page.sh "$VERSION" "CHANGELOG.md" "../ArduinoJson-$TAG-wandbox.txt" > "../ArduinoJson-$TAG.md"
echo "You can now copy ../ArduinoJson-$TAG.md into arduinojson.org/collections/_versions/$VERSION.md" echo "You can now copy ../ArduinoJson-$TAG.md into arduinojson.org/collections/_versions/$VERSION.md"

@ -58,6 +58,20 @@ TEST_CASE("string_view") {
doc.add(std::string_view("example two", 7)); doc.add(std::string_view("example two", 7));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8); REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8);
} }
SECTION("as<std::string_view>()") {
doc["s"] = "Hello World";
doc["i"] = 42;
REQUIRE(doc["s"].as<std::string_view>() == std::string_view("Hello World"));
REQUIRE(doc["i"].as<std::string_view>() == std::string_view());
}
SECTION("is<std::string_view>()") {
doc["s"] = "Hello World";
doc["i"] = 42;
REQUIRE(doc["s"].is<std::string_view>() == true);
REQUIRE(doc["i"].is<std::string_view>() == false);
}
} }
using ARDUINOJSON_NAMESPACE::adaptString; using ARDUINOJSON_NAMESPACE::adaptString;
@ -71,9 +85,5 @@ TEST_CASE("StringViewAdapter") {
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK_FALSE(adapter.equals(NULL));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }

@ -13,11 +13,10 @@ struct Date {
int year; int year;
}; };
bool convertToJson(const Date& src, JsonVariant dst) { void convertToJson(const Date& src, JsonVariant dst) {
dst["day"] = src.day; dst["day"] = src.day;
dst["month"] = src.month; dst["month"] = src.month;
dst["year"] = src.year; dst["year"] = src.year;
return true;
} }
void convertFromJson(JsonVariantConst src, Date& dst) { void convertFromJson(JsonVariantConst src, Date& dst) {
@ -92,10 +91,9 @@ class Complex {
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
template <> template <>
struct Converter<Complex> { struct Converter<Complex> {
static bool toJson(const Complex& src, VariantRef dst) { static void toJson(const Complex& src, VariantRef dst) {
dst["real"] = src.real(); dst["real"] = src.real();
dst["imag"] = src.imag(); dst["imag"] = src.imag();
return true;
} }
static Complex fromJson(VariantConstRef src) { static Complex fromJson(VariantConstRef src) {

@ -2,146 +2,118 @@
// Copyright Benoit Blanchon 2014-2021 // Copyright Benoit Blanchon 2014-2021
// MIT License // MIT License
#define ARDUINOJSON_ENABLE_PROGMEM 1
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#include "custom_string.hpp" #include "custom_string.hpp"
#include "progmem_emulation.hpp" #include "progmem_emulation.hpp"
#include "weird_strcmp.hpp" #include "weird_strcmp.hpp"
#include <ArduinoJson/Strings/ArduinoStringAdapter.hpp> #include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp>
#include <ArduinoJson/Strings/FlashStringAdapter.hpp>
#include <ArduinoJson/Strings/SizedRamStringAdapter.hpp>
#include <ArduinoJson/Strings/StdStringAdapter.hpp>
#include <catch.hpp> #include <catch.hpp>
using namespace ARDUINOJSON_NAMESPACE; using namespace ARDUINOJSON_NAMESPACE;
TEST_CASE("ConstRamStringAdapter") { TEST_CASE("const char*") {
SECTION("null") { SECTION("null") {
ConstRamStringAdapter adapter(NULL); StringAdapter<const char*> adapter(NULL);
CHECK(adapter.compare("bravo") < 0); CHECK(adapter.compare("bravo") < 0);
CHECK(adapter.compare(NULL) == 0); CHECK(adapter.compare(NULL) == 0);
CHECK(adapter.equals(NULL));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 0); CHECK(adapter.size() == 0);
} }
SECTION("non-null") { SECTION("non-null") {
ConstRamStringAdapter adapter("bravo"); StringAdapter<const char*> adapter("bravo");
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }
} }
TEST_CASE("SizedRamStringAdapter") { TEST_CASE("const char* + size") {
SECTION("null") { SECTION("null") {
SizedRamStringAdapter adapter(NULL, 10); StringAdapter<const char*, true> adapter(NULL, 10);
CHECK(adapter.compare("bravo") < 0); CHECK(adapter.compare("bravo") < 0);
CHECK(adapter.compare(NULL) == 0); CHECK(adapter.compare(NULL) == 0);
CHECK(adapter.equals(NULL));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 10); CHECK(adapter.size() == 10);
} }
SECTION("non-null") { SECTION("non-null") {
SizedRamStringAdapter adapter("bravo", 5); StringAdapter<const char*, true> adapter("bravo", 5);
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }
} }
TEST_CASE("FlashStringAdapter") { TEST_CASE("const __FlashStringHelper*") {
SECTION("null") { SECTION("null") {
FlashStringAdapter adapter(NULL); StringAdapter<const __FlashStringHelper*> adapter(NULL);
CHECK(adapter.compare("bravo") < 0); CHECK(adapter.compare("bravo") < 0);
CHECK(adapter.compare(NULL) == 0); CHECK(adapter.compare(NULL) == 0);
CHECK(adapter.equals(NULL));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 0); CHECK(adapter.size() == 0);
} }
SECTION("non-null") { SECTION("non-null") {
FlashStringAdapter adapter = adaptString(F("bravo")); StringAdapter<const __FlashStringHelper*> adapter = adaptString(F("bravo"));
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }
} }
TEST_CASE("std::string") { TEST_CASE("std::string") {
std::string str("bravo"); std::string str("bravo");
StdStringAdapter<std::string> adapter = adaptString(str); StringAdapter<std::string> adapter(str);
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }
TEST_CASE("Arduino String") { TEST_CASE("Arduino String") {
::String str("bravo"); ::String str("bravo");
ArduinoStringAdapter adapter = adaptString(str); StringAdapter< ::String> adapter(str);
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }
TEST_CASE("custom_string") { TEST_CASE("custom_string") {
custom_string str("bravo"); custom_string str("bravo");
StdStringAdapter<custom_string> adapter = adaptString(str); StringAdapter<custom_string> adapter(str);
CHECK(adapter.compare(NULL) > 0); CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0); CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0); CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0); CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK(adapter.size() == 5); CHECK(adapter.size() == 5);
} }

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

@ -1,5 +1,5 @@
name=ArduinoJson name=ArduinoJson
version=6.18.2 version=6.18.3
author=Benoit Blanchon <blog.benoitblanchon.fr> author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr> maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=A simple and efficient JSON library for embedded C++. sentence=A simple and efficient JSON library for embedded C++.

@ -173,8 +173,8 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
template <> template <>
struct Converter<ArrayConstRef> { struct Converter<ArrayConstRef> {
static bool toJson(VariantConstRef src, VariantRef dst) { static void toJson(VariantConstRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static ArrayConstRef fromJson(VariantConstRef src) { static ArrayConstRef fromJson(VariantConstRef src) {
@ -189,8 +189,8 @@ struct Converter<ArrayConstRef> {
template <> template <>
struct Converter<ArrayRef> { struct Converter<ArrayRef> {
static bool toJson(VariantConstRef src, VariantRef dst) { static void toJson(VariantConstRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static ArrayRef fromJson(VariantRef src) { static ArrayRef fromJson(VariantRef src) {

@ -178,8 +178,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return _array.getOrAddElement(_index); return _array.getOrAddElement(_index);
} }
friend bool convertToJson(const this_type& src, VariantRef dst) { friend void convertToJson(const this_type& src, VariantRef dst) {
return dst.set(src.getUpstreamElement()); dst.set(src.getUpstreamElement());
} }
TArray _array; TArray _array;

@ -62,9 +62,9 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
VariantData* var; VariantData* var;
if (s->key() != 0) { if (s->key() != 0) {
if (s->ownsKey()) if (s->ownsKey())
var = addMember(RamStringAdapter(s->key()), pool); var = addMember(adaptString(const_cast<char*>(s->key())), pool);
else else
var = addMember(ConstRamStringAdapter(s->key()), pool); var = addMember(adaptString(s->key()), pool);
} else { } else {
var = addElement(pool); var = addElement(pool);
} }
@ -107,7 +107,7 @@ template <typename TAdaptedString>
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
VariantSlot* slot = _head; VariantSlot* slot = _head;
while (slot) { while (slot) {
if (key.equals(slot->key())) if (key.compare(slot->key()) == 0)
break; break;
slot = slot->next(); slot = slot->next();
} }

@ -337,8 +337,8 @@ class JsonDocument : public Visitable {
JsonDocument& operator=(const JsonDocument&); JsonDocument& operator=(const JsonDocument&);
}; };
inline bool convertToJson(const JsonDocument& src, VariantRef dst) { inline void convertToJson(const JsonDocument& src, VariantRef dst) {
return dst.set(src.as<VariantConstRef>()); dst.set(src.as<VariantConstRef>());
} }
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

@ -167,7 +167,7 @@ class MemoryPool {
template <typename TAdaptedString> template <typename TAdaptedString>
const char* findString(const TAdaptedString& str) { const char* findString(const TAdaptedString& str) {
for (char* next = _begin; next < _left; ++next) { for (char* next = _begin; next < _left; ++next) {
if (str.equals(next)) if (str.compare(next) == 0)
return next; return next;
// jump to next terminator // jump to next terminator

@ -187,8 +187,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return _object.getOrAddMember(_key); return _object.getOrAddMember(_key);
} }
friend bool convertToJson(const this_type &src, VariantRef dst) { friend void convertToJson(const this_type &src, VariantRef dst) {
return dst.set(src.getUpstreamMember()); dst.set(src.getUpstreamMember());
} }
TObject _object; TObject _object;

@ -239,8 +239,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
template <> template <>
struct Converter<ObjectConstRef> { struct Converter<ObjectConstRef> {
static bool toJson(VariantConstRef src, VariantRef dst) { static void toJson(VariantConstRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static ObjectConstRef fromJson(VariantConstRef src) { static ObjectConstRef fromJson(VariantConstRef src) {
@ -255,8 +255,8 @@ struct Converter<ObjectConstRef> {
template <> template <>
struct Converter<ObjectRef> { struct Converter<ObjectRef> {
static bool toJson(VariantConstRef src, VariantRef dst) { static void toJson(VariantConstRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static ObjectRef fromJson(VariantRef src) { static ObjectRef fromJson(VariantRef src) {

@ -20,5 +20,6 @@
#include "type_traits/is_signed.hpp" #include "type_traits/is_signed.hpp"
#include "type_traits/is_unsigned.hpp" #include "type_traits/is_unsigned.hpp"
#include "type_traits/make_unsigned.hpp" #include "type_traits/make_unsigned.hpp"
#include "type_traits/make_void.hpp"
#include "type_traits/remove_const.hpp" #include "type_traits/remove_const.hpp"
#include "type_traits/remove_reference.hpp" #include "type_traits/remove_reference.hpp"

@ -0,0 +1,14 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
namespace ARDUINOJSON_NAMESPACE {
template <class = void>
struct make_void {
typedef void type;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,52 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <Arduino.h>
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter< ::String> {
public:
StringAdapter(const ::String& str) : _str(&str) {}
void copyTo(char* p, size_t n) const {
memcpy(p, _str->c_str(), n);
}
bool isNull() const {
// Arduino's String::c_str() can return NULL
return !_str->c_str();
}
int compare(const char* other) const {
// Arduino's String::c_str() can return NULL
const char* me = _str->c_str();
return safe_strcmp(me, other);
}
size_t size() const {
return _str->length();
}
typedef storage_policies::store_by_copy storage_policy;
private:
const ::String* _str;
};
template <>
class StringAdapter< ::StringSumHelper> : public StringAdapter< ::String> {
public:
StringAdapter< ::StringSumHelper>(const ::String& s)
: StringAdapter< ::String>(s) {}
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,51 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <stddef.h> // size_t
#include <string.h> // strcmp
#include <ArduinoJson/Polyfills/safe_strcmp.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter<const char*> {
public:
StringAdapter(const char* str = 0) : _str(str) {}
int compare(const char* other) const {
return safe_strcmp(_str, other);
}
bool isNull() const {
return !_str;
}
size_t size() const {
if (!_str)
return 0;
return strlen(_str);
}
const char* data() const {
return _str;
}
typedef storage_policies::store_by_address storage_policy;
protected:
const char* _str;
};
template <int N>
class StringAdapter<const char[N]> : public StringAdapter<const char*> {
public:
StringAdapter<const char[N]>(const char* s) : StringAdapter<const char*>(s) {}
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,48 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Polyfills/pgmspace.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter<const __FlashStringHelper*> {
public:
StringAdapter(const __FlashStringHelper* str) : _str(str) {}
int compare(const char* other) const {
if (!other && !_str)
return 0;
if (!_str)
return -1;
if (!other)
return 1;
return -strcmp_P(other, reinterpret_cast<const char*>(_str));
}
bool isNull() const {
return !_str;
}
void copyTo(char* p, size_t n) const {
memcpy_P(p, reinterpret_cast<const char*>(_str), n);
}
size_t size() const {
if (!_str)
return 0;
return strlen_P(reinterpret_cast<const char*>(_str));
}
typedef storage_policies::store_by_copy storage_policy;
private:
const __FlashStringHelper* _str;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,27 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Strings/Adapters/RamStringAdapter.hpp>
#include <ArduinoJson/Strings/String.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter<String> : public StringAdapter<char*> {
public:
StringAdapter(const String& str)
: StringAdapter<char*>(str.c_str()), _isStatic(str.isStatic()) {}
bool isStatic() const {
return _isStatic;
}
typedef storage_policies::decide_at_runtime storage_policy;
private:
bool _isStatic;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,29 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <typename TChar>
class StringAdapter<TChar*, false,
typename enable_if<sizeof(TChar) == 1 &&
!is_same<TChar, void>::value>::type>
: public StringAdapter<const char*> {
public:
StringAdapter(const TChar* str)
: StringAdapter<const char*>(reinterpret_cast<const char*>(str)) {}
void copyTo(char* p, size_t n) const {
memcpy(p, _str, n);
}
typedef ARDUINOJSON_NAMESPACE::storage_policies::store_by_copy storage_policy;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,48 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter<const __FlashStringHelper*, true> {
public:
StringAdapter(const __FlashStringHelper* str, size_t sz)
: _str(str), _size(sz) {}
int compare(const char* other) const {
if (!other && !_str)
return 0;
if (!_str)
return -1;
if (!other)
return 1;
return -strncmp_P(other, reinterpret_cast<const char*>(_str), _size);
}
bool isNull() const {
return !_str;
}
void copyTo(char* p, size_t n) const {
memcpy_P(p, reinterpret_cast<const char*>(_str), n);
}
size_t size() const {
return _size;
}
typedef storage_policies::store_by_copy storage_policy;
private:
const __FlashStringHelper* _str;
size_t _size;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,43 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
#include <string.h> // strcmp
namespace ARDUINOJSON_NAMESPACE {
template <typename TChar>
class StringAdapter<TChar*, true> {
public:
StringAdapter(const char* str, size_t n) : _str(str), _size(n) {}
int compare(const char* other) const {
return safe_strncmp(_str, other, _size);
}
bool isNull() const {
return !_str;
}
void copyTo(char* p, size_t n) const {
memcpy(p, _str, n);
}
size_t size() const {
return _size;
}
typedef storage_policies::store_by_copy storage_policy;
private:
const char* _str;
size_t _size;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,46 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
#include <string>
namespace ARDUINOJSON_NAMESPACE {
template <typename TCharTraits, typename TAllocator>
class StringAdapter<std::basic_string<char, TCharTraits, TAllocator> > {
public:
typedef std::basic_string<char, TCharTraits, TAllocator> string_type;
StringAdapter(const string_type& str) : _str(&str) {}
void copyTo(char* p, size_t n) const {
memcpy(p, _str->c_str(), n);
}
bool isNull() const {
return false;
}
int compare(const char* other) const {
if (!other)
return 1;
return _str->compare(other);
}
size_t size() const {
return _str->size();
}
typedef storage_policies::store_by_copy storage_policy;
private:
const string_type* _str;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,44 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
#include <string_view>
namespace ARDUINOJSON_NAMESPACE {
template <>
class StringAdapter<std::string_view> {
public:
StringAdapter(std::string_view str) : _str(str) {}
void copyTo(char* p, size_t n) const {
memcpy(p, _str.data(), n);
}
bool isNull() const {
return false;
}
int compare(const char* other) const {
if (!other)
return 1;
return _str.compare(other);
}
size_t size() const {
return _str.size();
}
typedef storage_policies::store_by_copy storage_policy;
private:
std::string_view _str;
};
} // namespace ARDUINOJSON_NAMESPACE

@ -4,10 +4,6 @@
#pragma once #pragma once
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp>
#include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
class String { class String {
@ -53,25 +49,4 @@ class String {
bool _isStatic; bool _isStatic;
}; };
class StringAdapter : public RamStringAdapter {
public:
StringAdapter(const String& str)
: RamStringAdapter(str.c_str()), _isStatic(str.isStatic()) {}
bool isStatic() const {
return _isStatic;
}
typedef storage_policies::decide_at_runtime storage_policy;
private:
bool _isStatic;
};
template <>
struct IsString<String> : true_type {};
inline StringAdapter adaptString(const String& str) {
return StringAdapter(str);
}
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

@ -0,0 +1,32 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Polyfills/type_traits.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <typename T, bool bounded = false, typename Enable = void>
class StringAdapter;
template <typename T>
inline StringAdapter<T, false> adaptString(const T& str) {
return StringAdapter<T, false>(str);
}
template <typename T>
inline StringAdapter<T, true> adaptString(const T& str, size_t sz) {
return StringAdapter<T, true>(str, sz);
}
template <typename T, typename Enable = void>
struct IsString : false_type {};
template <typename T>
struct IsString<
T, typename make_void<typename StringAdapter<T>::storage_policy>::type>
: true_type {};
} // namespace ARDUINOJSON_NAMESPACE

@ -4,23 +4,24 @@
#pragma once #pragma once
#include <ArduinoJson/Strings/ConstRamStringAdapter.hpp> #include <ArduinoJson/Strings/Adapters/ConstRamStringAdapter.hpp>
#include <ArduinoJson/Strings/RamStringAdapter.hpp> #include <ArduinoJson/Strings/Adapters/JsonStringAdapter.hpp>
#include <ArduinoJson/Strings/SizedRamStringAdapter.hpp> #include <ArduinoJson/Strings/Adapters/RamStringAdapter.hpp>
#include <ArduinoJson/Strings/Adapters/SizedRamStringAdapter.hpp>
#if ARDUINOJSON_ENABLE_STD_STRING #if ARDUINOJSON_ENABLE_STD_STRING
# include <ArduinoJson/Strings/StdStringAdapter.hpp> # include <ArduinoJson/Strings/Adapters/StdStringAdapter.hpp>
#endif #endif
#if ARDUINOJSON_ENABLE_STRING_VIEW #if ARDUINOJSON_ENABLE_STRING_VIEW
# include <ArduinoJson/Strings/StringViewAdapter.hpp> # include <ArduinoJson/Strings/Adapters/StringViewAdapter.hpp>
#endif #endif
#if ARDUINOJSON_ENABLE_ARDUINO_STRING #if ARDUINOJSON_ENABLE_ARDUINO_STRING
# include <ArduinoJson/Strings/ArduinoStringAdapter.hpp> # include <ArduinoJson/Strings/Adapters/ArduinoStringAdapter.hpp>
#endif #endif
#if ARDUINOJSON_ENABLE_PROGMEM #if ARDUINOJSON_ENABLE_PROGMEM
# include <ArduinoJson/Strings/FlashStringAdapter.hpp> # include <ArduinoJson/Strings/Adapters/FlashStringAdapter.hpp>
# include <ArduinoJson/Strings/SizedFlashStringAdapter.hpp> # include <ArduinoJson/Strings/Adapters/SizedFlashStringAdapter.hpp>
#endif #endif

@ -12,9 +12,9 @@ namespace ARDUINOJSON_NAMESPACE {
template <typename T, typename Enable> template <typename T, typename Enable>
struct Converter { struct Converter {
static bool toJson(const T& src, VariantRef dst) { static void toJson(const T& src, VariantRef dst) {
// clang-format off // clang-format off
return convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/ convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/
// clang-format on // clang-format on
} }
@ -38,13 +38,11 @@ template <typename T>
struct Converter< struct Converter<
T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value && T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
!is_same<char, T>::value>::type> { !is_same<char, T>::value>::type> {
static bool toJson(T src, VariantRef dst) { static void toJson(T src, VariantRef dst) {
VariantData* data = getData(dst); VariantData* data = getData(dst);
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
if (!data) if (data)
return false;
data->setInteger(src); data->setInteger(src);
return true;
} }
static T fromJson(VariantConstRef src) { static T fromJson(VariantConstRef src) {
@ -61,8 +59,8 @@ struct Converter<
template <typename T> template <typename T>
struct Converter<T, typename enable_if<is_enum<T>::value>::type> { struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
static bool toJson(T src, VariantRef dst) { static void toJson(T src, VariantRef dst) {
return dst.set(static_cast<Integer>(src)); dst.set(static_cast<Integer>(src));
} }
static T fromJson(VariantConstRef src) { static T fromJson(VariantConstRef src) {
@ -78,12 +76,10 @@ struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
template <> template <>
struct Converter<bool> { struct Converter<bool> {
static bool toJson(bool src, VariantRef dst) { static void toJson(bool src, VariantRef dst) {
VariantData* data = getData(dst); VariantData* data = getData(dst);
if (!data) if (data)
return false;
data->setBoolean(src); data->setBoolean(src);
return true;
} }
static bool fromJson(VariantConstRef src) { static bool fromJson(VariantConstRef src) {
@ -99,12 +95,10 @@ struct Converter<bool> {
template <typename T> template <typename T>
struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> { struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
static bool toJson(T src, VariantRef dst) { static void toJson(T src, VariantRef dst) {
VariantData* data = getData(dst); VariantData* data = getData(dst);
if (!data) if (data)
return false;
data->setFloat(static_cast<Float>(src)); data->setFloat(static_cast<Float>(src));
return true;
} }
static T fromJson(VariantConstRef src) { static T fromJson(VariantConstRef src) {
@ -120,8 +114,8 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
template <> template <>
struct Converter<const char*> { struct Converter<const char*> {
static bool toJson(const char* src, VariantRef dst) { static void toJson(const char* src, VariantRef dst) {
return variantSetString(getData(dst), adaptString(src), getPool(dst)); variantSetString(getData(dst), adaptString(src), getPool(dst));
} }
static const char* fromJson(VariantConstRef src) { static const char* fromJson(VariantConstRef src) {
@ -163,12 +157,10 @@ canConvertFromJson(VariantConstRef src, const T&) {
template <> template <>
struct Converter<SerializedValue<const char*> > { struct Converter<SerializedValue<const char*> > {
static bool toJson(SerializedValue<const char*> src, VariantRef dst) { static void toJson(SerializedValue<const char*> src, VariantRef dst) {
VariantData* data = getData(dst); VariantData* data = getData(dst);
if (!data) if (data)
return false;
data->setLinkedRaw(src); data->setLinkedRaw(src);
return true;
} }
}; };
@ -178,10 +170,11 @@ struct Converter<SerializedValue<const char*> > {
template <typename T> template <typename T>
struct Converter<SerializedValue<T>, struct Converter<SerializedValue<T>,
typename enable_if<!is_same<const char*, T>::value>::type> { typename enable_if<!is_same<const char*, T>::value>::type> {
static bool toJson(SerializedValue<T> src, VariantRef dst) { static void toJson(SerializedValue<T> src, VariantRef dst) {
VariantData* data = getData(dst); VariantData* data = getData(dst);
MemoryPool* pool = getPool(dst); MemoryPool* pool = getPool(dst);
return data != 0 && data->setOwnedRaw(src, pool); if (data)
data->setOwnedRaw(src, pool);
} }
}; };
@ -189,9 +182,8 @@ struct Converter<SerializedValue<T>,
template <> template <>
struct Converter<decltype(nullptr)> { struct Converter<decltype(nullptr)> {
static bool toJson(decltype(nullptr), VariantRef dst) { static void toJson(decltype(nullptr), VariantRef dst) {
variantSetNull(getData(dst)); variantSetNull(getData(dst));
return true;
} }
static decltype(nullptr) fromJson(VariantConstRef) { static decltype(nullptr) fromJson(VariantConstRef) {
return nullptr; return nullptr;
@ -247,20 +239,33 @@ class MemoryPoolPrint : public Print {
size_t _capacity; size_t _capacity;
}; };
inline bool convertToJson(const ::Printable& src, VariantRef dst) { inline void convertToJson(const ::Printable& src, VariantRef dst) {
MemoryPool* pool = getPool(dst); MemoryPool* pool = getPool(dst);
VariantData* data = getData(dst); VariantData* data = getData(dst);
if (!pool || !data) if (!pool || !data)
return false; return;
MemoryPoolPrint print(pool); MemoryPoolPrint print(pool);
src.printTo(print); src.printTo(print);
if (print.overflowed()) { if (print.overflowed()) {
pool->markAsOverflowed(); pool->markAsOverflowed();
data->setNull(); data->setNull();
return false; return;
} }
data->setStringPointer(print.c_str(), storage_policies::store_by_copy()); data->setStringPointer(print.c_str(), storage_policies::store_by_copy());
return true; }
#endif
#if ARDUINOJSON_ENABLE_STRING_VIEW
inline void convertFromJson(VariantConstRef src, std::string_view& dst) {
const char* str = src.as<const char*>();
if (str) // the standard doesn't allow passing null to the constructor
dst = std::string_view(str);
}
inline bool canConvertFromJson(VariantConstRef src, const std::string_view&) {
return src.is<const char*>();
} }
#endif #endif

@ -8,7 +8,7 @@
#include <ArduinoJson/Misc/Visitable.hpp> #include <ArduinoJson/Misc/Visitable.hpp>
#include <ArduinoJson/Numbers/arithmeticCompare.hpp> #include <ArduinoJson/Numbers/arithmeticCompare.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp> #include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Strings/IsString.hpp> #include <ArduinoJson/Strings/StringAdapter.hpp>
#include <ArduinoJson/Variant/Visitor.hpp> #include <ArduinoJson/Variant/Visitor.hpp>
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {

@ -7,7 +7,7 @@
#include <ArduinoJson/Memory/MemoryPool.hpp> #include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Misc/SerializedValue.hpp> #include <ArduinoJson/Misc/SerializedValue.hpp>
#include <ArduinoJson/Numbers/convertNumber.hpp> #include <ArduinoJson/Numbers/convertNumber.hpp>
#include <ArduinoJson/Strings/RamStringAdapter.hpp> #include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/VariantContent.hpp> #include <ArduinoJson/Variant/VariantContent.hpp>
// VariantData can't have a constructor (to be a POD), so we have no way to fix // VariantData can't have a constructor (to be a POD), so we have no way to fix
@ -103,7 +103,8 @@ class VariantData {
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
return toObject().copyFrom(src._content.asCollection, pool); return toObject().copyFrom(src._content.asCollection, pool);
case VALUE_IS_OWNED_STRING: case VALUE_IS_OWNED_STRING:
return setString(RamStringAdapter(src._content.asString), pool); return setString(adaptString(const_cast<char *>(src._content.asString)),
pool);
case VALUE_IS_OWNED_RAW: case VALUE_IS_OWNED_RAW:
return setOwnedRaw( return setOwnedRaw(
serialized(src._content.asRaw.data, src._content.asRaw.size), pool); serialized(src._content.asRaw.data, src._content.asRaw.size), pool);

@ -85,7 +85,8 @@ class VariantRef : public VariantRefBase<VariantData>,
template <typename T> template <typename T>
FORCE_INLINE bool set(const T &value) const { FORCE_INLINE bool set(const T &value) const {
return Converter<T>::toJson(value, *this); Converter<T>::toJson(value, *this);
return _pool && !_pool->overflowed();
} }
bool ARDUINOJSON_DEPRECATED( bool ARDUINOJSON_DEPRECATED(
@ -94,7 +95,8 @@ class VariantRef : public VariantRefBase<VariantData>,
template <typename T> template <typename T>
FORCE_INLINE bool set(T *value) const { FORCE_INLINE bool set(T *value) const {
return Converter<T *>::toJson(value, *this); Converter<T *>::toJson(value, *this);
return _pool && !_pool->overflowed();
} }
template <typename T> template <typename T>
@ -339,8 +341,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
template <> template <>
struct Converter<VariantRef> { struct Converter<VariantRef> {
static bool toJson(VariantRef src, VariantRef dst) { static void toJson(VariantRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static VariantRef fromJson(VariantRef src) { static VariantRef fromJson(VariantRef src) {
@ -362,8 +364,8 @@ struct Converter<VariantRef> {
template <> template <>
struct Converter<VariantConstRef> { struct Converter<VariantConstRef> {
static bool toJson(VariantConstRef src, VariantRef dst) { static void toJson(VariantConstRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst)); variantCopyFrom(getData(dst), getData(src), getPool(dst));
} }
static VariantConstRef fromJson(VariantConstRef src) { static VariantConstRef fromJson(VariantConstRef src) {

@ -4,7 +4,7 @@
#pragma once #pragma once
#define ARDUINOJSON_VERSION "6.18.2" #define ARDUINOJSON_VERSION "6.18.3"
#define ARDUINOJSON_VERSION_MAJOR 6 #define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 18 #define ARDUINOJSON_VERSION_MINOR 18
#define ARDUINOJSON_VERSION_REVISION 2 #define ARDUINOJSON_VERSION_REVISION 3

Loading…
Cancel
Save