mirror of
				https://github.com/gabrielkheisa/antares-esp8266-mqtt.git
				synced 2025-11-04 06:49:22 +00:00 
			
		
		
		
	Added subscribe functionality
This commit is contained in:
		@@ -10,11 +10,18 @@
 | 
			
		||||
AntaresESP8266MQTT antares(ACCESSKEY);
 | 
			
		||||
 | 
			
		||||
void setup() {
 | 
			
		||||
	Serial.begin(115200);
 | 
			
		||||
	antares.setDebug(true);
 | 
			
		||||
	antares.wifiConnection(WIFISSID, PASSWORD);
 | 
			
		||||
	antares.setMqttServer();
 | 
			
		||||
  Serial.begin(115200);
 | 
			
		||||
  antares.setDebug(true);
 | 
			
		||||
  antares.wifiConnection(WIFISSID, PASSWORD);
 | 
			
		||||
  antares.setMqttServer();
 | 
			
		||||
}
 | 
			
		||||
void loop() {
 | 
			
		||||
  antares.checkMqttConnection();
 | 
			
		||||
 | 
			
		||||
  antares.add("temperature", 30);
 | 
			
		||||
  antares.add("humidity", 75);
 | 
			
		||||
  antares.add("message", "Hello World!");
 | 
			
		||||
  antares.add("temperature", 45);
 | 
			
		||||
  antares.publish(projectName, deviceName);
 | 
			
		||||
  delay(5000);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								examples/AntaresMQTTSubscribe/AntaresMQTTSubscribe.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								examples/AntaresMQTTSubscribe/AntaresMQTTSubscribe.ino
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
#include <AntaresESP8266MQTT.h>
 | 
			
		||||
 | 
			
		||||
#define ACCESSKEY "your-access-key"
 | 
			
		||||
#define WIFISSID "your-wifi-ssid"
 | 
			
		||||
#define PASSWORD "your-wifi-password"
 | 
			
		||||
 | 
			
		||||
#define projectName = "your-project-name";
 | 
			
		||||
#define deviceName = "your-device-name";
 | 
			
		||||
 | 
			
		||||
AntaresESP8266MQTT antares(ACCESSKEY);
 | 
			
		||||
 | 
			
		||||
void callback(char topic[], byte payload[], unsigned int length) {
 | 
			
		||||
  String topicString = String(topic);
 | 
			
		||||
  String payloadString = antares.byteToString(payload, length);
 | 
			
		||||
  
 | 
			
		||||
  Serial.println("[ANTARES] New Mesage: ");
 | 
			
		||||
  Serial.println(topicString);
 | 
			
		||||
  Serial.println(payloadString);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void setup() {
 | 
			
		||||
  Serial.begin(115200);
 | 
			
		||||
  antares.setDebug(true);
 | 
			
		||||
  antares.wifiConnection(WIFISSID, PASSWORD);
 | 
			
		||||
  antares.setMqttServer();
 | 
			
		||||
  antares.setCallback(callback);
 | 
			
		||||
}
 | 
			
		||||
void loop() {
 | 
			
		||||
  antares.checkMqttConnection();
 | 
			
		||||
}
 | 
			
		||||
@@ -16,7 +16,7 @@ wifiConnection	KEYWORD2
 | 
			
		||||
setDebug	KEYWORD2
 | 
			
		||||
printDebug	KEYWORD2
 | 
			
		||||
ipToString	KEYWORD2
 | 
			
		||||
setMqttserver	KEYWORD2
 | 
			
		||||
setMqttServer	KEYWORD2
 | 
			
		||||
checkMqttConnection	KEYWORD2
 | 
			
		||||
 | 
			
		||||
######################################
 | 
			
		||||
 
 | 
			
		||||
@@ -19,12 +19,22 @@ void AntaresESP8266MQTT::setMqttServer() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::checkMqttConnection() {
 | 
			
		||||
    _subscriptionTopic = "/oneM2M/req/" + _accessKey + "/antares-cse/json";
 | 
			
		||||
 | 
			
		||||
    if(!client.connected()) {
 | 
			
		||||
        while(!client.connected()) {
 | 
			
		||||
            printDebug("[ANTARES] Attempting MQTT connection...\n");
 | 
			
		||||
            if(client.connect("ESP8266-TESTVALIAN")) {
 | 
			
		||||
                printDebug("[ANTARES] Connected!");
 | 
			
		||||
                client.publish("testvalian", "connect!");
 | 
			
		||||
                char subscriptionTopicChar[_subscriptionTopic.length() + 1];
 | 
			
		||||
                _subscriptionTopic.toCharArray(subscriptionTopicChar, _subscriptionTopic.length() + 1);
 | 
			
		||||
 | 
			
		||||
                Serial.println();
 | 
			
		||||
                Serial.print("[ANTARES] Topic: ");
 | 
			
		||||
                Serial.println(subscriptionTopicChar);
 | 
			
		||||
 | 
			
		||||
                client.publish(subscriptionTopicChar, "connect!");
 | 
			
		||||
                client.subscribe(subscriptionTopicChar);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                printDebug("[ANTARES] Failed, rc=" + String(client.state()) + ", Will try again in 5 secs.\n");
 | 
			
		||||
@@ -67,7 +77,45 @@ bool AntaresESP8266MQTT::wifiConnection(String SSID, String wifiPassword) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::add(String key, int value) {
 | 
			
		||||
    DynamicJsonBuffer jsonBuffer;
 | 
			
		||||
    JsonObject& object = jsonBuffer.parseObject(_jsonDataString);
 | 
			
		||||
    object[key] = value;
 | 
			
		||||
    String newInsert;
 | 
			
		||||
    object.printTo(newInsert);
 | 
			
		||||
    _jsonDataString = newInsert;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::add(String key, float value) {
 | 
			
		||||
    DynamicJsonBuffer jsonBuffer;
 | 
			
		||||
    JsonObject& object = jsonBuffer.parseObject(_jsonDataString);
 | 
			
		||||
    object[key] = value;
 | 
			
		||||
    String newInsert;
 | 
			
		||||
    object.printTo(newInsert);
 | 
			
		||||
    _jsonDataString = newInsert;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::add(String key, double value) {
 | 
			
		||||
    DynamicJsonBuffer jsonBuffer;
 | 
			
		||||
    JsonObject& object = jsonBuffer.parseObject(_jsonDataString);
 | 
			
		||||
    object[key] = value;
 | 
			
		||||
    String newInsert;
 | 
			
		||||
    object.printTo(newInsert);
 | 
			
		||||
    _jsonDataString = newInsert;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::add(String key, String value) {
 | 
			
		||||
    DynamicJsonBuffer jsonBuffer;
 | 
			
		||||
    JsonObject& object = jsonBuffer.parseObject(_jsonDataString);
 | 
			
		||||
    object[key] = value;
 | 
			
		||||
    String newInsert;
 | 
			
		||||
    object.printTo(newInsert);
 | 
			
		||||
    _jsonDataString = newInsert;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::printData() {
 | 
			
		||||
    printDebug("[ANTARES] " + _jsonDataString + "\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::printDebug(String text) {
 | 
			
		||||
    if(_debug) {
 | 
			
		||||
@@ -75,13 +123,42 @@ void AntaresESP8266MQTT::printDebug(String text) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::publish(String projectName, String deviceName) {
 | 
			
		||||
    String topic = "/oneM2M/req/" + _accessKey + "/antares-cse/json";
 | 
			
		||||
    char jsonDataChar[_jsonDataString.length() + 1];
 | 
			
		||||
    char topicChar[topic.length() + 1];
 | 
			
		||||
 | 
			
		||||
    _jsonDataString.toCharArray(jsonDataChar, _jsonDataString.length() + 1);
 | 
			
		||||
    topic.toCharArray(topicChar, topic.length() + 1);
 | 
			
		||||
 | 
			
		||||
    _jsonDataString = "{}";
 | 
			
		||||
 | 
			
		||||
    client.publish(topicChar, jsonDataChar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::setCallback(std::function<void(char*, uint8_t*, unsigned int)> callbackFunc) {
 | 
			
		||||
    client.setCallback(callbackFunc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AntaresESP8266MQTT::setDebug(bool trueFalse) {
 | 
			
		||||
    _debug = trueFalse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AntaresESP8266MQTT::byteToString(byte* payload, unsigned int length) {
 | 
			
		||||
    String payloadString;
 | 
			
		||||
    for(int i = 0; i < length; i++) {
 | 
			
		||||
        payloadString += char(payload[i]);
 | 
			
		||||
    }
 | 
			
		||||
    return payloadString;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String AntaresESP8266MQTT::ipToString(IPAddress ip) {
 | 
			
		||||
    String s="";
 | 
			
		||||
    for (int i=0; i<4; i++)
 | 
			
		||||
      s += i  ? "." + String(ip[i]) : String(ip[i]);
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AntaresESP8266MQTT::setSubscriptionTopic() {
 | 
			
		||||
    _subscriptionTopic = "/oneM2M/req/" + _accessKey + "/antares-cse/json";
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@
 | 
			
		||||
#include <Arduino.h>
 | 
			
		||||
#include <ESP8266WiFi.h>
 | 
			
		||||
#include <PubSubClient.h>
 | 
			
		||||
#include <ArduinoJson.h>
 | 
			
		||||
 | 
			
		||||
class AntaresESP8266MQTT {
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +16,8 @@ private:
 | 
			
		||||
    char* _wifiSSID;
 | 
			
		||||
    char* _wifiPass;
 | 
			
		||||
    String _accessKey;
 | 
			
		||||
    String _jsonDataString = "{}";
 | 
			
		||||
    String _subscriptionTopic;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    AntaresESP8266MQTT(String accessKey);
 | 
			
		||||
@@ -22,9 +25,20 @@ public:
 | 
			
		||||
    bool setDebug(bool trueFalse);
 | 
			
		||||
    void printDebug(String text);
 | 
			
		||||
    String ipToString(IPAddress ip);
 | 
			
		||||
    /* Overloaded functions: Add data to temporary storage */
 | 
			
		||||
    void add(String key, int value);
 | 
			
		||||
    void add(String key, float value);
 | 
			
		||||
    void add(String key, double value);
 | 
			
		||||
    void add(String key, String value);
 | 
			
		||||
    /* Overloaded functions end */
 | 
			
		||||
    void printData();
 | 
			
		||||
    void publish(String projectName, String deviceName);
 | 
			
		||||
 | 
			
		||||
    void setMqttServer();
 | 
			
		||||
    void checkMqttConnection();
 | 
			
		||||
    void setCallback(std::function<void(char*, uint8_t*, unsigned int)> callbackFunc);
 | 
			
		||||
    String byteToString(byte* payload, unsigned int length);
 | 
			
		||||
    void setSubscriptionTopic();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								src/ArduinoJson.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								src/ArduinoJson.h
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 | 
			
		||||
#include "ArduinoJson.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace ArduinoJson;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										17
									
								
								src/ArduinoJson.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								src/ArduinoJson.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "ArduinoJson/DynamicJsonBuffer.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonArray.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonObject.hpp"
 | 
			
		||||
#include "ArduinoJson/StaticJsonBuffer.hpp"
 | 
			
		||||
 | 
			
		||||
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonArrayImpl.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonBufferImpl.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonObjectImpl.hpp"
 | 
			
		||||
#include "ArduinoJson/JsonVariantImpl.hpp"
 | 
			
		||||
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
 | 
			
		||||
							
								
								
									
										151
									
								
								src/ArduinoJson/Configuration.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										151
									
								
								src/ArduinoJson/Configuration.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// Small or big machine?
 | 
			
		||||
#ifndef ARDUINOJSON_EMBEDDED_MODE
 | 
			
		||||
#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__) || defined(__XC) || \
 | 
			
		||||
    defined(__ARMCC_VERSION)
 | 
			
		||||
#define ARDUINOJSON_EMBEDDED_MODE 1
 | 
			
		||||
#else
 | 
			
		||||
#define ARDUINOJSON_EMBEDDED_MODE 0
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_EMBEDDED_MODE
 | 
			
		||||
 | 
			
		||||
// Store floats by default to reduce the memory usage (issue #134)
 | 
			
		||||
#ifndef ARDUINOJSON_USE_DOUBLE
 | 
			
		||||
#define ARDUINOJSON_USE_DOUBLE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Store longs by default, because they usually match the size of a float.
 | 
			
		||||
#ifndef ARDUINOJSON_USE_LONG_LONG
 | 
			
		||||
#define ARDUINOJSON_USE_LONG_LONG 0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ARDUINOJSON_USE_INT64
 | 
			
		||||
#define ARDUINOJSON_USE_INT64 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Embedded systems usually don't have std::string
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
 | 
			
		||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Embedded systems usually don't have std::stream
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Limit nesting as the stack is likely to be small
 | 
			
		||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
 | 
			
		||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else  // ARDUINOJSON_EMBEDDED_MODE
 | 
			
		||||
 | 
			
		||||
// On a computer we have plenty of memory so we can use doubles
 | 
			
		||||
#ifndef ARDUINOJSON_USE_DOUBLE
 | 
			
		||||
#define ARDUINOJSON_USE_DOUBLE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Use long long when available
 | 
			
		||||
#ifndef ARDUINOJSON_USE_LONG_LONG
 | 
			
		||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
 | 
			
		||||
#define ARDUINOJSON_USE_LONG_LONG 1
 | 
			
		||||
#else
 | 
			
		||||
#define ARDUINOJSON_USE_LONG_LONG 0
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Use _int64 on old versions of Visual Studio
 | 
			
		||||
#ifndef ARDUINOJSON_USE_INT64
 | 
			
		||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
 | 
			
		||||
#define ARDUINOJSON_USE_INT64 1
 | 
			
		||||
#else
 | 
			
		||||
#define ARDUINOJSON_USE_INT64 0
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// On a computer, we can use std::string
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
 | 
			
		||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// On a computer, we can assume std::stream
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// On a computer, the stack is large so we can increase nesting limit
 | 
			
		||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
 | 
			
		||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // ARDUINOJSON_EMBEDDED_MODE
 | 
			
		||||
 | 
			
		||||
#ifdef ARDUINO
 | 
			
		||||
 | 
			
		||||
// Enable support for Arduino String
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Enable support for Arduino Stream
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else  // ARDUINO
 | 
			
		||||
 | 
			
		||||
// Disable support for Arduino String
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Disable support for Arduino Stream
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif  // ARDUINO
 | 
			
		||||
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
 | 
			
		||||
#ifdef PROGMEM
 | 
			
		||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
 | 
			
		||||
#else
 | 
			
		||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
 | 
			
		||||
#ifdef ARDUINO_ARCH_AVR
 | 
			
		||||
// alignment isn't needed for 8-bit AVR
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
 | 
			
		||||
#else
 | 
			
		||||
// but most processors need pointers to be align on word size
 | 
			
		||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Enable deprecated functions by default
 | 
			
		||||
#ifndef ARDUINOJSON_ENABLE_DEPRECATED
 | 
			
		||||
#define ARDUINOJSON_ENABLE_DEPRECATED 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Control the exponentiation threshold for big numbers
 | 
			
		||||
// CAUTION: cannot be more that 1e9 !!!!
 | 
			
		||||
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
 | 
			
		||||
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Control the exponentiation threshold for small numbers
 | 
			
		||||
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
 | 
			
		||||
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
 | 
			
		||||
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										37
									
								
								src/ArduinoJson/Data/Encoding.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										37
									
								
								src/ArduinoJson/Data/Encoding.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
class Encoding {
 | 
			
		||||
 public:
 | 
			
		||||
  // Optimized for code size on a 8-bit AVR
 | 
			
		||||
  static char escapeChar(char c) {
 | 
			
		||||
    const char *p = escapeTable(false);
 | 
			
		||||
    while (p[0] && p[1] != c) {
 | 
			
		||||
      p += 2;
 | 
			
		||||
    }
 | 
			
		||||
    return p[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Optimized for code size on a 8-bit AVR
 | 
			
		||||
  static char unescapeChar(char c) {
 | 
			
		||||
    const char *p = escapeTable(true);
 | 
			
		||||
    for (;;) {
 | 
			
		||||
      if (p[0] == '\0') return c;
 | 
			
		||||
      if (p[0] == c) return p[1];
 | 
			
		||||
      p += 2;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  static const char *escapeTable(bool excludeIdenticals) {
 | 
			
		||||
    return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0];
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/ArduinoJson/Data/JsonBufferAllocated.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								src/ArduinoJson/Data/JsonBufferAllocated.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../JsonBuffer.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
class JsonBufferAllocated {
 | 
			
		||||
 public:
 | 
			
		||||
  void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() {
 | 
			
		||||
    if (!jsonBuffer) return NULL;
 | 
			
		||||
    return jsonBuffer->alloc(n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void operator delete(void *, JsonBuffer *)throw();
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/ArduinoJson/Data/JsonFloat.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								src/ArduinoJson/Data/JsonFloat.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_USE_DOUBLE
 | 
			
		||||
typedef double JsonFloat;
 | 
			
		||||
#else
 | 
			
		||||
typedef float JsonFloat;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/ArduinoJson/Data/JsonInteger.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								src/ArduinoJson/Data/JsonInteger.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_USE_LONG_LONG
 | 
			
		||||
typedef long long JsonInteger;
 | 
			
		||||
typedef unsigned long long JsonUInt;
 | 
			
		||||
#elif ARDUINOJSON_USE_INT64
 | 
			
		||||
typedef __int64 JsonInteger;
 | 
			
		||||
typedef unsigned _int64 JsonUInt;
 | 
			
		||||
#else
 | 
			
		||||
typedef long JsonInteger;
 | 
			
		||||
typedef unsigned long JsonUInt;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/ArduinoJson/Data/JsonVariantAs.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										42
									
								
								src/ArduinoJson/Data/JsonVariantAs.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A metafunction that returns the type of the value returned by
 | 
			
		||||
// JsonVariant::as<T>()
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct JsonVariantAs {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantAs<char*> {
 | 
			
		||||
  typedef const char* type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantAs<JsonArray> {
 | 
			
		||||
  typedef JsonArray& type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantAs<const JsonArray> {
 | 
			
		||||
  typedef const JsonArray& type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantAs<JsonObject> {
 | 
			
		||||
  typedef JsonObject& type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantAs<const JsonObject> {
 | 
			
		||||
  typedef const JsonObject& type;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/ArduinoJson/Data/JsonVariantContent.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								src/ArduinoJson/Data/JsonVariantContent.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonFloat.hpp"
 | 
			
		||||
#include "JsonInteger.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// Forward declarations
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonObject;
 | 
			
		||||
 | 
			
		||||
namespace Internals {
 | 
			
		||||
// A union that defines the actual content of a JsonVariant.
 | 
			
		||||
// The enum JsonVariantType determines which member is in use.
 | 
			
		||||
union JsonVariantContent {
 | 
			
		||||
  JsonFloat asFloat;     // used for double and float
 | 
			
		||||
  JsonUInt asInteger;    // used for bool, char, short, int and longs
 | 
			
		||||
  const char* asString;  // asString can be null
 | 
			
		||||
  JsonArray* asArray;    // asArray cannot be null
 | 
			
		||||
  JsonObject* asObject;  // asObject cannot be null
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/ArduinoJson/Data/JsonVariantDefault.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								src/ArduinoJson/Data/JsonVariantDefault.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct JsonVariantDefault {
 | 
			
		||||
  static T get() {
 | 
			
		||||
    return T();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct JsonVariantDefault<const T> : JsonVariantDefault<T> {};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct JsonVariantDefault<T&> : JsonVariantDefault<T> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/ArduinoJson/Data/JsonVariantType.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								src/ArduinoJson/Data/JsonVariantType.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonObject;
 | 
			
		||||
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Enumerated type to know the current type of a JsonVariant.
 | 
			
		||||
// The value determines which member of JsonVariantContent is used.
 | 
			
		||||
enum JsonVariantType {
 | 
			
		||||
  JSON_UNDEFINED,         // JsonVariant has not been initialized
 | 
			
		||||
  JSON_UNPARSED,          // JsonVariant contains an unparsed string
 | 
			
		||||
  JSON_STRING,            // JsonVariant stores a const char*
 | 
			
		||||
  JSON_BOOLEAN,           // JsonVariant stores a bool
 | 
			
		||||
  JSON_POSITIVE_INTEGER,  // JsonVariant stores an JsonUInt
 | 
			
		||||
  JSON_NEGATIVE_INTEGER,  // JsonVariant stores an JsonUInt that must be negated
 | 
			
		||||
  JSON_ARRAY,             // JsonVariant stores a pointer to a JsonArray
 | 
			
		||||
  JSON_OBJECT,            // JsonVariant stores a pointer to a JsonObject
 | 
			
		||||
  JSON_FLOAT              // JsonVariant stores a JsonFloat
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								src/ArduinoJson/Data/List.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										94
									
								
								src/ArduinoJson/Data/List.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../JsonBuffer.hpp"
 | 
			
		||||
#include "ListConstIterator.hpp"
 | 
			
		||||
#include "ListIterator.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A singly linked list of T.
 | 
			
		||||
// The linked list is composed of ListNode<T>.
 | 
			
		||||
// It is derived by JsonArray and JsonObject
 | 
			
		||||
template <typename T>
 | 
			
		||||
class List {
 | 
			
		||||
 public:
 | 
			
		||||
  typedef T value_type;
 | 
			
		||||
  typedef ListNode<T> node_type;
 | 
			
		||||
  typedef ListIterator<T> iterator;
 | 
			
		||||
  typedef ListConstIterator<T> const_iterator;
 | 
			
		||||
 | 
			
		||||
  // Creates an empty List<T> attached to a JsonBuffer.
 | 
			
		||||
  // The JsonBuffer allows to allocate new nodes.
 | 
			
		||||
  // When buffer is NULL, the List is not able to grow and success() returns
 | 
			
		||||
  // false. This is used to identify bad memory allocations and parsing
 | 
			
		||||
  // failures.
 | 
			
		||||
  explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
 | 
			
		||||
 | 
			
		||||
  // Returns true if the object is valid
 | 
			
		||||
  // Would return false in the following situation:
 | 
			
		||||
  // - the memory allocation failed (StaticJsonBuffer was too small)
 | 
			
		||||
  // - the JSON parsing failed
 | 
			
		||||
  bool success() const {
 | 
			
		||||
    return _buffer != NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns the numbers of elements in the list.
 | 
			
		||||
  // For a JsonObject, it would return the number of key-value pairs
 | 
			
		||||
  size_t size() const {
 | 
			
		||||
    size_t nodeCount = 0;
 | 
			
		||||
    for (node_type *node = _firstNode; node; node = node->next) nodeCount++;
 | 
			
		||||
    return nodeCount;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iterator add() {
 | 
			
		||||
    node_type *newNode = new (_buffer) node_type();
 | 
			
		||||
 | 
			
		||||
    if (_firstNode) {
 | 
			
		||||
      node_type *lastNode = _firstNode;
 | 
			
		||||
      while (lastNode->next) lastNode = lastNode->next;
 | 
			
		||||
      lastNode->next = newNode;
 | 
			
		||||
    } else {
 | 
			
		||||
      _firstNode = newNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return iterator(newNode);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iterator begin() {
 | 
			
		||||
    return iterator(_firstNode);
 | 
			
		||||
  }
 | 
			
		||||
  iterator end() {
 | 
			
		||||
    return iterator(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const_iterator begin() const {
 | 
			
		||||
    return const_iterator(_firstNode);
 | 
			
		||||
  }
 | 
			
		||||
  const_iterator end() const {
 | 
			
		||||
    return const_iterator(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void remove(iterator it) {
 | 
			
		||||
    node_type *nodeToRemove = it._node;
 | 
			
		||||
    if (!nodeToRemove) return;
 | 
			
		||||
    if (nodeToRemove == _firstNode) {
 | 
			
		||||
      _firstNode = nodeToRemove->next;
 | 
			
		||||
    } else {
 | 
			
		||||
      for (node_type *node = _firstNode; node; node = node->next)
 | 
			
		||||
        if (node->next == nodeToRemove) node->next = nodeToRemove->next;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  JsonBuffer *_buffer;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  node_type *_firstNode;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								src/ArduinoJson/Data/ListConstIterator.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								src/ArduinoJson/Data/ListConstIterator.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "ListNode.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A read-only forward itertor for List<T>
 | 
			
		||||
template <typename T>
 | 
			
		||||
class ListConstIterator {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit ListConstIterator(const ListNode<T> *node = NULL) : _node(node) {}
 | 
			
		||||
 | 
			
		||||
  const T &operator*() const {
 | 
			
		||||
    return _node->content;
 | 
			
		||||
  }
 | 
			
		||||
  const T *operator->() {
 | 
			
		||||
    return &_node->content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator==(const ListConstIterator<T> &other) const {
 | 
			
		||||
    return _node == other._node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator!=(const ListConstIterator<T> &other) const {
 | 
			
		||||
    return _node != other._node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ListConstIterator<T> &operator++() {
 | 
			
		||||
    if (_node) _node = _node->next;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ListConstIterator<T> &operator+=(size_t distance) {
 | 
			
		||||
    while (_node && distance) {
 | 
			
		||||
      _node = _node->next;
 | 
			
		||||
      --distance;
 | 
			
		||||
    }
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const ListNode<T> *_node;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								src/ArduinoJson/Data/ListIterator.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										60
									
								
								src/ArduinoJson/Data/ListIterator.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "ListConstIterator.hpp"
 | 
			
		||||
#include "ListNode.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class List;
 | 
			
		||||
 | 
			
		||||
// A read-write forward iterator for List<T>
 | 
			
		||||
template <typename T>
 | 
			
		||||
class ListIterator {
 | 
			
		||||
  friend class List<T>;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  explicit ListIterator(ListNode<T> *node = NULL) : _node(node) {}
 | 
			
		||||
 | 
			
		||||
  T &operator*() const {
 | 
			
		||||
    return _node->content;
 | 
			
		||||
  }
 | 
			
		||||
  T *operator->() {
 | 
			
		||||
    return &_node->content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator==(const ListIterator<T> &other) const {
 | 
			
		||||
    return _node == other._node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator!=(const ListIterator<T> &other) const {
 | 
			
		||||
    return _node != other._node;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ListIterator<T> &operator++() {
 | 
			
		||||
    if (_node) _node = _node->next;
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ListIterator<T> &operator+=(size_t distance) {
 | 
			
		||||
    while (_node && distance) {
 | 
			
		||||
      _node = _node->next;
 | 
			
		||||
      --distance;
 | 
			
		||||
    }
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  operator ListConstIterator<T>() const {
 | 
			
		||||
    return ListConstIterator<T>(_node);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  ListNode<T> *_node;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ArduinoJson/Data/ListNode.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								src/ArduinoJson/Data/ListNode.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>  // for NULL
 | 
			
		||||
 | 
			
		||||
#include "JsonBufferAllocated.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A node for a singly-linked list.
 | 
			
		||||
// Used by List<T> and its iterators.
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct ListNode : public Internals::JsonBufferAllocated {
 | 
			
		||||
  ListNode() throw() : next(NULL) {}
 | 
			
		||||
 | 
			
		||||
  ListNode<T> *next;
 | 
			
		||||
  T content;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/ArduinoJson/Data/NonCopyable.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								src/ArduinoJson/Data/NonCopyable.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A type that cannot be copied
 | 
			
		||||
class NonCopyable {
 | 
			
		||||
 protected:
 | 
			
		||||
  NonCopyable() {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // copy constructor is private
 | 
			
		||||
  NonCopyable(const NonCopyable&);
 | 
			
		||||
 | 
			
		||||
  // copy operator is private
 | 
			
		||||
  NonCopyable& operator=(const NonCopyable&);
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ArduinoJson/Data/ReferenceType.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								src/ArduinoJson/Data/ReferenceType.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A type that is meant to be used by reference only (JsonArray and JsonObject)
 | 
			
		||||
class ReferenceType {
 | 
			
		||||
 public:
 | 
			
		||||
  bool operator==(const ReferenceType& other) const {
 | 
			
		||||
    // two JsonArray are equal if they are the same instance
 | 
			
		||||
    // (we don't compare the content)
 | 
			
		||||
    return this == &other;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator!=(const ReferenceType& other) const {
 | 
			
		||||
    return this != &other;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/ArduinoJson/Data/ValueSetter.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										48
									
								
								src/ArduinoJson/Data/ValueSetter.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../JsonBuffer.hpp"
 | 
			
		||||
#include "../JsonVariant.hpp"
 | 
			
		||||
#include "../StringTraits/StringTraits.hpp"
 | 
			
		||||
#include "../TypeTraits/EnableIf.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TSourceRef, typename Enable = void>
 | 
			
		||||
struct ValueSetter {
 | 
			
		||||
  template <typename TDestination>
 | 
			
		||||
  static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
 | 
			
		||||
    destination = source;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TSourceRef>
 | 
			
		||||
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<StringTraits<
 | 
			
		||||
                                   TSourceRef>::should_duplicate>::type> {
 | 
			
		||||
  template <typename TDestination>
 | 
			
		||||
  static bool set(JsonBuffer* buffer, TDestination& destination,
 | 
			
		||||
                  TSourceRef source) {
 | 
			
		||||
    const char* copy = buffer->strdup(source);
 | 
			
		||||
    if (!copy) return false;
 | 
			
		||||
    destination = copy;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TSourceRef>
 | 
			
		||||
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<!StringTraits<
 | 
			
		||||
                                   TSourceRef>::should_duplicate>::type> {
 | 
			
		||||
  template <typename TDestination>
 | 
			
		||||
  static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
 | 
			
		||||
    // unsigned char* -> char*
 | 
			
		||||
    destination = reinterpret_cast<const char*>(source);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								src/ArduinoJson/Deserialization/Comments.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										61
									
								
								src/ArduinoJson/Deserialization/Comments.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
template <typename TInput>
 | 
			
		||||
void skipSpacesAndComments(TInput& input) {
 | 
			
		||||
  for (;;) {
 | 
			
		||||
    switch (input.current()) {
 | 
			
		||||
      // spaces
 | 
			
		||||
      case ' ':
 | 
			
		||||
      case '\t':
 | 
			
		||||
      case '\r':
 | 
			
		||||
      case '\n':
 | 
			
		||||
        input.move();
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      // comments
 | 
			
		||||
      case '/':
 | 
			
		||||
        switch (input.next()) {
 | 
			
		||||
          // C-style block comment
 | 
			
		||||
          case '*':
 | 
			
		||||
            input.move();  // skip '/'
 | 
			
		||||
            // no need to skip '*'
 | 
			
		||||
            for (;;) {
 | 
			
		||||
              input.move();
 | 
			
		||||
              if (input.current() == '\0') return;
 | 
			
		||||
              if (input.current() == '*' && input.next() == '/') {
 | 
			
		||||
                input.move();  // skip '*'
 | 
			
		||||
                input.move();  // skip '/'
 | 
			
		||||
                break;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          // C++-style line comment
 | 
			
		||||
          case '/':
 | 
			
		||||
            // not need to skip "//"
 | 
			
		||||
            for (;;) {
 | 
			
		||||
              input.move();
 | 
			
		||||
              if (input.current() == '\0') return;
 | 
			
		||||
              if (input.current() == '\n') break;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
          // not a comment, just a '/'
 | 
			
		||||
          default:
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								src/ArduinoJson/Deserialization/JsonParser.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										104
									
								
								src/ArduinoJson/Deserialization/JsonParser.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../JsonBuffer.hpp"
 | 
			
		||||
#include "../JsonVariant.hpp"
 | 
			
		||||
#include "../TypeTraits/IsConst.hpp"
 | 
			
		||||
#include "StringWriter.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Parse JSON string to create JsonArrays and JsonObjects
 | 
			
		||||
// This internal class is not indended to be used directly.
 | 
			
		||||
// Instead, use JsonBuffer.parseArray() or .parseObject()
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
class JsonParser {
 | 
			
		||||
 public:
 | 
			
		||||
  JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer,
 | 
			
		||||
             uint8_t nestingLimit)
 | 
			
		||||
      : _buffer(buffer),
 | 
			
		||||
        _reader(reader),
 | 
			
		||||
        _writer(writer),
 | 
			
		||||
        _nestingLimit(nestingLimit) {}
 | 
			
		||||
 | 
			
		||||
  JsonArray &parseArray();
 | 
			
		||||
  JsonObject &parseObject();
 | 
			
		||||
 | 
			
		||||
  JsonVariant parseVariant() {
 | 
			
		||||
    JsonVariant result;
 | 
			
		||||
    parseAnythingTo(&result);
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  JsonParser &operator=(const JsonParser &);  // non-copiable
 | 
			
		||||
 | 
			
		||||
  static bool eat(TReader &, char charToSkip);
 | 
			
		||||
  FORCE_INLINE bool eat(char charToSkip) {
 | 
			
		||||
    return eat(_reader, charToSkip);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const char *parseString();
 | 
			
		||||
  bool parseAnythingTo(JsonVariant *destination);
 | 
			
		||||
  FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
 | 
			
		||||
 | 
			
		||||
  inline bool parseArrayTo(JsonVariant *destination);
 | 
			
		||||
  inline bool parseObjectTo(JsonVariant *destination);
 | 
			
		||||
  inline bool parseStringTo(JsonVariant *destination);
 | 
			
		||||
 | 
			
		||||
  static inline bool isInRange(char c, char min, char max) {
 | 
			
		||||
    return min <= c && c <= max;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static inline bool isLetterOrNumber(char c) {
 | 
			
		||||
    return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
 | 
			
		||||
           isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static inline bool isQuote(char c) {
 | 
			
		||||
    return c == '\'' || c == '\"';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  JsonBuffer *_buffer;
 | 
			
		||||
  TReader _reader;
 | 
			
		||||
  TWriter _writer;
 | 
			
		||||
  uint8_t _nestingLimit;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TJsonBuffer, typename TString, typename Enable = void>
 | 
			
		||||
struct JsonParserBuilder {
 | 
			
		||||
  typedef typename Internals::StringTraits<TString>::Reader InputReader;
 | 
			
		||||
  typedef JsonParser<InputReader, TJsonBuffer &> TParser;
 | 
			
		||||
 | 
			
		||||
  static TParser makeParser(TJsonBuffer *buffer, TString &json,
 | 
			
		||||
                            uint8_t nestingLimit) {
 | 
			
		||||
    return TParser(buffer, InputReader(json), *buffer, nestingLimit);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TJsonBuffer, typename TChar>
 | 
			
		||||
struct JsonParserBuilder<
 | 
			
		||||
    TJsonBuffer, TChar *,
 | 
			
		||||
    typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value>::type> {
 | 
			
		||||
  typedef typename Internals::StringTraits<TChar *>::Reader TReader;
 | 
			
		||||
  typedef StringWriter<TChar> TWriter;
 | 
			
		||||
  typedef JsonParser<TReader, TWriter> TParser;
 | 
			
		||||
 | 
			
		||||
  static TParser makeParser(TJsonBuffer *buffer, TChar *json,
 | 
			
		||||
                            uint8_t nestingLimit) {
 | 
			
		||||
    return TParser(buffer, TReader(json), TWriter(json), nestingLimit);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TJsonBuffer, typename TString>
 | 
			
		||||
inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser(
 | 
			
		||||
    TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) {
 | 
			
		||||
  return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json,
 | 
			
		||||
                                                             nestingLimit);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										193
									
								
								src/ArduinoJson/Deserialization/JsonParserImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										193
									
								
								src/ArduinoJson/Deserialization/JsonParserImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,193 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Comments.hpp"
 | 
			
		||||
#include "JsonParser.hpp"
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
 | 
			
		||||
    TReader &reader, char charToSkip) {
 | 
			
		||||
  skipSpacesAndComments(reader);
 | 
			
		||||
  if (reader.current() != charToSkip) return false;
 | 
			
		||||
  reader.move();
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool
 | 
			
		||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
 | 
			
		||||
    JsonVariant *destination) {
 | 
			
		||||
  if (_nestingLimit == 0) return false;
 | 
			
		||||
  _nestingLimit--;
 | 
			
		||||
  bool success = parseAnythingToUnsafe(destination);
 | 
			
		||||
  _nestingLimit++;
 | 
			
		||||
  return success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool
 | 
			
		||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
 | 
			
		||||
    JsonVariant *destination) {
 | 
			
		||||
  skipSpacesAndComments(_reader);
 | 
			
		||||
 | 
			
		||||
  switch (_reader.current()) {
 | 
			
		||||
    case '[':
 | 
			
		||||
      return parseArrayTo(destination);
 | 
			
		||||
 | 
			
		||||
    case '{':
 | 
			
		||||
      return parseObjectTo(destination);
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      return parseStringTo(destination);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline ArduinoJson::JsonArray &
 | 
			
		||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
 | 
			
		||||
  // Create an empty array
 | 
			
		||||
  JsonArray &array = _buffer->createArray();
 | 
			
		||||
 | 
			
		||||
  // Check opening braket
 | 
			
		||||
  if (!eat('[')) goto ERROR_MISSING_BRACKET;
 | 
			
		||||
  if (eat(']')) goto SUCCESS_EMPTY_ARRAY;
 | 
			
		||||
 | 
			
		||||
  // Read each value
 | 
			
		||||
  for (;;) {
 | 
			
		||||
    // 1 - Parse value
 | 
			
		||||
    JsonVariant value;
 | 
			
		||||
    if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
 | 
			
		||||
    if (!array.add(value)) goto ERROR_NO_MEMORY;
 | 
			
		||||
 | 
			
		||||
    // 2 - More values?
 | 
			
		||||
    if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY;
 | 
			
		||||
    if (!eat(',')) goto ERROR_MISSING_COMMA;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
SUCCESS_EMPTY_ARRAY:
 | 
			
		||||
SUCCES_NON_EMPTY_ARRAY:
 | 
			
		||||
  return array;
 | 
			
		||||
 | 
			
		||||
ERROR_INVALID_VALUE:
 | 
			
		||||
ERROR_MISSING_BRACKET:
 | 
			
		||||
ERROR_MISSING_COMMA:
 | 
			
		||||
ERROR_NO_MEMORY:
 | 
			
		||||
  return JsonArray::invalid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
 | 
			
		||||
    JsonVariant *destination) {
 | 
			
		||||
  JsonArray &array = parseArray();
 | 
			
		||||
  if (!array.success()) return false;
 | 
			
		||||
 | 
			
		||||
  *destination = array;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline ArduinoJson::JsonObject &
 | 
			
		||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
 | 
			
		||||
  // Create an empty object
 | 
			
		||||
  JsonObject &object = _buffer->createObject();
 | 
			
		||||
 | 
			
		||||
  // Check opening brace
 | 
			
		||||
  if (!eat('{')) goto ERROR_MISSING_BRACE;
 | 
			
		||||
  if (eat('}')) goto SUCCESS_EMPTY_OBJECT;
 | 
			
		||||
 | 
			
		||||
  // Read each key value pair
 | 
			
		||||
  for (;;) {
 | 
			
		||||
    // 1 - Parse key
 | 
			
		||||
    const char *key = parseString();
 | 
			
		||||
    if (!key) goto ERROR_INVALID_KEY;
 | 
			
		||||
    if (!eat(':')) goto ERROR_MISSING_COLON;
 | 
			
		||||
 | 
			
		||||
    // 2 - Parse value
 | 
			
		||||
    JsonVariant value;
 | 
			
		||||
    if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
 | 
			
		||||
    if (!object.set(key, value)) goto ERROR_NO_MEMORY;
 | 
			
		||||
 | 
			
		||||
    // 3 - More keys/values?
 | 
			
		||||
    if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT;
 | 
			
		||||
    if (!eat(',')) goto ERROR_MISSING_COMMA;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
SUCCESS_EMPTY_OBJECT:
 | 
			
		||||
SUCCESS_NON_EMPTY_OBJECT:
 | 
			
		||||
  return object;
 | 
			
		||||
 | 
			
		||||
ERROR_INVALID_KEY:
 | 
			
		||||
ERROR_INVALID_VALUE:
 | 
			
		||||
ERROR_MISSING_BRACE:
 | 
			
		||||
ERROR_MISSING_COLON:
 | 
			
		||||
ERROR_MISSING_COMMA:
 | 
			
		||||
ERROR_NO_MEMORY:
 | 
			
		||||
  return JsonObject::invalid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
 | 
			
		||||
    JsonVariant *destination) {
 | 
			
		||||
  JsonObject &object = parseObject();
 | 
			
		||||
  if (!object.success()) return false;
 | 
			
		||||
 | 
			
		||||
  *destination = object;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline const char *
 | 
			
		||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
 | 
			
		||||
  typename TypeTraits::RemoveReference<TWriter>::type::String str =
 | 
			
		||||
      _writer.startString();
 | 
			
		||||
 | 
			
		||||
  skipSpacesAndComments(_reader);
 | 
			
		||||
  char c = _reader.current();
 | 
			
		||||
 | 
			
		||||
  if (isQuote(c)) {  // quotes
 | 
			
		||||
    _reader.move();
 | 
			
		||||
    char stopChar = c;
 | 
			
		||||
    for (;;) {
 | 
			
		||||
      c = _reader.current();
 | 
			
		||||
      if (c == '\0') break;
 | 
			
		||||
      _reader.move();
 | 
			
		||||
 | 
			
		||||
      if (c == stopChar) break;
 | 
			
		||||
 | 
			
		||||
      if (c == '\\') {
 | 
			
		||||
        // replace char
 | 
			
		||||
        c = Encoding::unescapeChar(_reader.current());
 | 
			
		||||
        if (c == '\0') break;
 | 
			
		||||
        _reader.move();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      str.append(c);
 | 
			
		||||
    }
 | 
			
		||||
  } else {  // no quotes
 | 
			
		||||
    for (;;) {
 | 
			
		||||
      if (!isLetterOrNumber(c)) break;
 | 
			
		||||
      _reader.move();
 | 
			
		||||
      str.append(c);
 | 
			
		||||
      c = _reader.current();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return str.c_str();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TReader, typename TWriter>
 | 
			
		||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo(
 | 
			
		||||
    JsonVariant *destination) {
 | 
			
		||||
  bool hasQuotes = isQuote(_reader.current());
 | 
			
		||||
  const char *value = parseString();
 | 
			
		||||
  if (value == NULL) return false;
 | 
			
		||||
  if (hasQuotes) {
 | 
			
		||||
    *destination = value;
 | 
			
		||||
  } else {
 | 
			
		||||
    *destination = RawJson(value);
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								src/ArduinoJson/Deserialization/StringWriter.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								src/ArduinoJson/Deserialization/StringWriter.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TChar>
 | 
			
		||||
class StringWriter {
 | 
			
		||||
 public:
 | 
			
		||||
  class String {
 | 
			
		||||
   public:
 | 
			
		||||
    String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
 | 
			
		||||
 | 
			
		||||
    void append(char c) {
 | 
			
		||||
      *(*_writePtr)++ = TChar(c);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char* c_str() const {
 | 
			
		||||
      *(*_writePtr)++ = 0;
 | 
			
		||||
      return reinterpret_cast<const char*>(_startPtr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    TChar** _writePtr;
 | 
			
		||||
    TChar* _startPtr;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  StringWriter(TChar* buffer) : _ptr(buffer) {}
 | 
			
		||||
 | 
			
		||||
  String startString() {
 | 
			
		||||
    return String(&_ptr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  TChar* _ptr;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										167
									
								
								src/ArduinoJson/DynamicJsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										167
									
								
								src/ArduinoJson/DynamicJsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonBufferBase.hpp"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic push
 | 
			
		||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#endif
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
class DefaultAllocator {
 | 
			
		||||
 public:
 | 
			
		||||
  void* allocate(size_t size) {
 | 
			
		||||
    return malloc(size);
 | 
			
		||||
  }
 | 
			
		||||
  void deallocate(void* pointer) {
 | 
			
		||||
    free(pointer);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TAllocator>
 | 
			
		||||
class DynamicJsonBufferBase
 | 
			
		||||
    : public JsonBufferBase<DynamicJsonBufferBase<TAllocator> > {
 | 
			
		||||
  struct Block;
 | 
			
		||||
  struct EmptyBlock {
 | 
			
		||||
    Block* next;
 | 
			
		||||
    size_t capacity;
 | 
			
		||||
    size_t size;
 | 
			
		||||
  };
 | 
			
		||||
  struct Block : EmptyBlock {
 | 
			
		||||
    uint8_t data[1];
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  enum { EmptyBlockSize = sizeof(EmptyBlock) };
 | 
			
		||||
 | 
			
		||||
  DynamicJsonBufferBase(size_t initialSize = 256)
 | 
			
		||||
      : _head(NULL), _nextBlockCapacity(initialSize) {}
 | 
			
		||||
 | 
			
		||||
  ~DynamicJsonBufferBase() {
 | 
			
		||||
    clear();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the number of bytes occupied in the buffer
 | 
			
		||||
  size_t size() const {
 | 
			
		||||
    size_t total = 0;
 | 
			
		||||
    for (const Block* b = _head; b; b = b->next) total += b->size;
 | 
			
		||||
    return total;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocates the specified amount of bytes in the buffer
 | 
			
		||||
  virtual void* alloc(size_t bytes) {
 | 
			
		||||
    alignNextAlloc();
 | 
			
		||||
    return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Resets the buffer.
 | 
			
		||||
  // USE WITH CAUTION: this invalidates all previously allocated data
 | 
			
		||||
  void clear() {
 | 
			
		||||
    Block* currentBlock = _head;
 | 
			
		||||
    while (currentBlock != NULL) {
 | 
			
		||||
      _nextBlockCapacity = currentBlock->capacity;
 | 
			
		||||
      Block* nextBlock = currentBlock->next;
 | 
			
		||||
      _allocator.deallocate(currentBlock);
 | 
			
		||||
      currentBlock = nextBlock;
 | 
			
		||||
    }
 | 
			
		||||
    _head = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  class String {
 | 
			
		||||
   public:
 | 
			
		||||
    String(DynamicJsonBufferBase* parent)
 | 
			
		||||
        : _parent(parent), _start(NULL), _length(0) {}
 | 
			
		||||
 | 
			
		||||
    void append(char c) {
 | 
			
		||||
      if (_parent->canAllocInHead(1)) {
 | 
			
		||||
        char* end = static_cast<char*>(_parent->allocInHead(1));
 | 
			
		||||
        *end = c;
 | 
			
		||||
        if (_length == 0) _start = end;
 | 
			
		||||
      } else {
 | 
			
		||||
        char* newStart =
 | 
			
		||||
            static_cast<char*>(_parent->allocInNewBlock(_length + 1));
 | 
			
		||||
        if (_start && newStart) memcpy(newStart, _start, _length);
 | 
			
		||||
        if (newStart) newStart[_length] = c;
 | 
			
		||||
        _start = newStart;
 | 
			
		||||
      }
 | 
			
		||||
      _length++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char* c_str() {
 | 
			
		||||
      append(0);
 | 
			
		||||
      return _start;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    DynamicJsonBufferBase* _parent;
 | 
			
		||||
    char* _start;
 | 
			
		||||
    size_t _length;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  String startString() {
 | 
			
		||||
    return String(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  void alignNextAlloc() {
 | 
			
		||||
    if (_head) _head->size = this->round_size_up(_head->size);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool canAllocInHead(size_t bytes) const {
 | 
			
		||||
    return _head != NULL && _head->size + bytes <= _head->capacity;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void* allocInHead(size_t bytes) {
 | 
			
		||||
    void* p = _head->data + _head->size;
 | 
			
		||||
    _head->size += bytes;
 | 
			
		||||
    return p;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void* allocInNewBlock(size_t bytes) {
 | 
			
		||||
    size_t capacity = _nextBlockCapacity;
 | 
			
		||||
    if (bytes > capacity) capacity = bytes;
 | 
			
		||||
    if (!addNewBlock(capacity)) return NULL;
 | 
			
		||||
    _nextBlockCapacity *= 2;
 | 
			
		||||
    return allocInHead(bytes);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool addNewBlock(size_t capacity) {
 | 
			
		||||
    size_t bytes = EmptyBlockSize + capacity;
 | 
			
		||||
    Block* block = static_cast<Block*>(_allocator.allocate(bytes));
 | 
			
		||||
    if (block == NULL) return false;
 | 
			
		||||
    block->capacity = capacity;
 | 
			
		||||
    block->size = 0;
 | 
			
		||||
    block->next = _head;
 | 
			
		||||
    _head = block;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TAllocator _allocator;
 | 
			
		||||
  Block* _head;
 | 
			
		||||
  size_t _nextBlockCapacity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic pop
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Implements a JsonBuffer with dynamic memory allocation.
 | 
			
		||||
// You are strongly encouraged to consider using StaticJsonBuffer which is much
 | 
			
		||||
// more suitable for embedded systems.
 | 
			
		||||
typedef DynamicJsonBufferBase<DefaultAllocator> DynamicJsonBuffer;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										230
									
								
								src/ArduinoJson/JsonArray.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										230
									
								
								src/ArduinoJson/JsonArray.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,230 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonBufferAllocated.hpp"
 | 
			
		||||
#include "Data/List.hpp"
 | 
			
		||||
#include "Data/ReferenceType.hpp"
 | 
			
		||||
#include "Data/ValueSetter.hpp"
 | 
			
		||||
#include "JsonVariant.hpp"
 | 
			
		||||
#include "Serialization/JsonPrintable.hpp"
 | 
			
		||||
#include "StringTraits/StringTraits.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "TypeTraits/IsArray.hpp"
 | 
			
		||||
#include "TypeTraits/IsFloatingPoint.hpp"
 | 
			
		||||
#include "TypeTraits/IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
// Returns the size (in bytes) of an array with n elements.
 | 
			
		||||
// Can be very handy to determine the size of a StaticJsonBuffer.
 | 
			
		||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
 | 
			
		||||
  (sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// Forward declarations
 | 
			
		||||
class JsonObject;
 | 
			
		||||
class JsonBuffer;
 | 
			
		||||
class JsonArraySubscript;
 | 
			
		||||
 | 
			
		||||
// An array of JsonVariant.
 | 
			
		||||
//
 | 
			
		||||
// The constructor is private, instances must be created via
 | 
			
		||||
// JsonBuffer::createArray() or JsonBuffer::parseArray().
 | 
			
		||||
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
 | 
			
		||||
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
 | 
			
		||||
class JsonArray : public Internals::JsonPrintable<JsonArray>,
 | 
			
		||||
                  public Internals::ReferenceType,
 | 
			
		||||
                  public Internals::NonCopyable,
 | 
			
		||||
                  public Internals::List<JsonVariant>,
 | 
			
		||||
                  public Internals::JsonBufferAllocated {
 | 
			
		||||
 public:
 | 
			
		||||
  // Create an empty JsonArray attached to the specified JsonBuffer.
 | 
			
		||||
  // You should not call this constructor directly.
 | 
			
		||||
  // Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
 | 
			
		||||
  explicit JsonArray(JsonBuffer *buffer) throw()
 | 
			
		||||
      : Internals::List<JsonVariant>(buffer) {}
 | 
			
		||||
 | 
			
		||||
  // Gets the value at the specified index
 | 
			
		||||
  const JsonArraySubscript operator[](size_t index) const;
 | 
			
		||||
 | 
			
		||||
  // Gets or sets the value at specified index
 | 
			
		||||
  JsonArraySubscript operator[](size_t index);
 | 
			
		||||
 | 
			
		||||
  // Adds the specified value at the end of the array.
 | 
			
		||||
  //
 | 
			
		||||
  // bool add(TValue);
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
 | 
			
		||||
      const T &value) {
 | 
			
		||||
    return add_impl<const T &>(value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool add(TValue);
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  bool add(const T *value) {
 | 
			
		||||
    return add_impl<const T *>(value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool add(TValue value, uint8_t decimals);
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  bool add(T value, uint8_t) {
 | 
			
		||||
    return add_impl<const JsonVariant &>(JsonVariant(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Sets the value at specified index.
 | 
			
		||||
  //
 | 
			
		||||
  // bool add(size_t index, TValue);
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set(
 | 
			
		||||
      size_t index, const T &value) {
 | 
			
		||||
    return set_impl<const T &>(index, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool add(size_t index, TValue);
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  bool set(size_t index, const T *value) {
 | 
			
		||||
    return set_impl<const T *>(index, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(size_t index, TValue value, uint8_t decimals);
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  set(size_t index, T value, uint8_t decimals) {
 | 
			
		||||
    return set_impl<const JsonVariant &>(index, JsonVariant(value, decimals));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the value at the specified index.
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename Internals::JsonVariantAs<T>::type get(size_t index) const {
 | 
			
		||||
    const_iterator it = begin() += index;
 | 
			
		||||
    return it != end() ? it->as<T>() : Internals::JsonVariantDefault<T>::get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check the type of the value at specified index.
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  bool is(size_t index) const {
 | 
			
		||||
    const_iterator it = begin() += index;
 | 
			
		||||
    return it != end() ? it->is<T>() : false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Creates a JsonArray and adds a reference at the end of the array.
 | 
			
		||||
  // It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
 | 
			
		||||
  JsonArray &createNestedArray();
 | 
			
		||||
 | 
			
		||||
  // Creates a JsonObject and adds a reference at the end of the array.
 | 
			
		||||
  // It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
 | 
			
		||||
  JsonObject &createNestedObject();
 | 
			
		||||
 | 
			
		||||
  // Removes element at specified index.
 | 
			
		||||
  void remove(size_t index) {
 | 
			
		||||
    remove(begin() += index);
 | 
			
		||||
  }
 | 
			
		||||
  using Internals::List<JsonVariant>::remove;
 | 
			
		||||
 | 
			
		||||
  // Returns a reference an invalid JsonArray.
 | 
			
		||||
  // This object is meant to replace a NULL pointer.
 | 
			
		||||
  // This is used when memory allocation or JSON parsing fail.
 | 
			
		||||
  static JsonArray &invalid() {
 | 
			
		||||
    static JsonArray instance(NULL);
 | 
			
		||||
    return instance;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Imports a 1D array
 | 
			
		||||
  template <typename T, size_t N>
 | 
			
		||||
  bool copyFrom(T (&array)[N]) {
 | 
			
		||||
    return copyFrom(array, N);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Imports a 1D array
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  bool copyFrom(T *array, size_t len) {
 | 
			
		||||
    bool ok = true;
 | 
			
		||||
    for (size_t i = 0; i < len; i++) {
 | 
			
		||||
      ok &= add(array[i]);
 | 
			
		||||
    }
 | 
			
		||||
    return ok;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Imports a 2D array
 | 
			
		||||
  template <typename T, size_t N1, size_t N2>
 | 
			
		||||
  bool copyFrom(T (&array)[N1][N2]) {
 | 
			
		||||
    bool ok = true;
 | 
			
		||||
    for (size_t i = 0; i < N1; i++) {
 | 
			
		||||
      JsonArray &nestedArray = createNestedArray();
 | 
			
		||||
      for (size_t j = 0; j < N2; j++) {
 | 
			
		||||
        ok &= nestedArray.add(array[i][j]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return ok;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Exports a 1D array
 | 
			
		||||
  template <typename T, size_t N>
 | 
			
		||||
  size_t copyTo(T (&array)[N]) const {
 | 
			
		||||
    return copyTo(array, N);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Exports a 1D array
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  size_t copyTo(T *array, size_t len) const {
 | 
			
		||||
    size_t i = 0;
 | 
			
		||||
    for (const_iterator it = begin(); it != end() && i < len; ++it)
 | 
			
		||||
      array[i++] = *it;
 | 
			
		||||
    return i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Exports a 2D array
 | 
			
		||||
  template <typename T, size_t N1, size_t N2>
 | 
			
		||||
  void copyTo(T (&array)[N1][N2]) const {
 | 
			
		||||
    size_t i = 0;
 | 
			
		||||
    for (const_iterator it = begin(); it != end() && i < N1; ++it) {
 | 
			
		||||
      it->as<JsonArray>().copyTo(array[i++]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_DEPRECATED
 | 
			
		||||
  DEPRECATED("use remove() instead")
 | 
			
		||||
  FORCE_INLINE void removeAt(size_t index) {
 | 
			
		||||
    return remove(index);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  template <typename TValueRef>
 | 
			
		||||
  bool set_impl(size_t index, TValueRef value) {
 | 
			
		||||
    iterator it = begin() += index;
 | 
			
		||||
    if (it == end()) return false;
 | 
			
		||||
    return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TValueRef>
 | 
			
		||||
  bool add_impl(TValueRef value) {
 | 
			
		||||
    iterator it = Internals::List<JsonVariant>::add();
 | 
			
		||||
    if (it == end()) return false;
 | 
			
		||||
    return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace Internals {
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantDefault<JsonArray> {
 | 
			
		||||
  static JsonArray &get() {
 | 
			
		||||
    return JsonArray::invalid();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								src/ArduinoJson/JsonArrayImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										26
									
								
								src/ArduinoJson/JsonArrayImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonArray.hpp"
 | 
			
		||||
#include "JsonArraySubscript.hpp"
 | 
			
		||||
#include "JsonObject.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
inline JsonArray &JsonArray::createNestedArray() {
 | 
			
		||||
  if (!_buffer) return JsonArray::invalid();
 | 
			
		||||
  JsonArray &array = _buffer->createArray();
 | 
			
		||||
  add(array);
 | 
			
		||||
  return array;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline JsonObject &JsonArray::createNestedObject() {
 | 
			
		||||
  if (!_buffer) return JsonObject::invalid();
 | 
			
		||||
  JsonObject &object = _buffer->createObject();
 | 
			
		||||
  add(object);
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										122
									
								
								src/ArduinoJson/JsonArraySubscript.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										122
									
								
								src/ArduinoJson/JsonArraySubscript.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,122 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Configuration.hpp"
 | 
			
		||||
#include "JsonVariantBase.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4522)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
 | 
			
		||||
 public:
 | 
			
		||||
  FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
 | 
			
		||||
      : _array(array), _index(index) {}
 | 
			
		||||
 | 
			
		||||
  FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
 | 
			
		||||
    _array.set(_index, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Replaces the value
 | 
			
		||||
  //
 | 
			
		||||
  // operator=(TValue)
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
 | 
			
		||||
    _array.set(_index, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // operator=(TValue)
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  FORCE_INLINE JsonArraySubscript& operator=(const T* src) {
 | 
			
		||||
    _array.set(_index, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FORCE_INLINE bool success() const {
 | 
			
		||||
    return _index < _array.size();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
 | 
			
		||||
    return _array.get<T>(_index);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  FORCE_INLINE bool is() const {
 | 
			
		||||
    return _array.is<T>(_index);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Replaces the value
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue)
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE bool set(const TValue& value) {
 | 
			
		||||
    return _array.set(_index, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue)
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE bool set(const TValue* value) {
 | 
			
		||||
    return _array.set(_index, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue, uint8_t decimals);
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  FORCE_INLINE bool set(const TValue& value, uint8_t) {
 | 
			
		||||
    return _array.set(_index, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  JsonArray& _array;
 | 
			
		||||
  const size_t _index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
inline std::ostream& operator<<(std::ostream& os,
 | 
			
		||||
                                const JsonArraySubscript& source) {
 | 
			
		||||
  return source.printTo(os);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline JsonArraySubscript JsonArray::operator[](size_t index) {
 | 
			
		||||
  return JsonArraySubscript(*this, index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline const JsonArraySubscript JsonArray::operator[](size_t index) const {
 | 
			
		||||
  return JsonArraySubscript(*const_cast<JsonArray*>(this), index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
inline JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
 | 
			
		||||
    size_t index) {
 | 
			
		||||
  return impl()->template as<JsonArray>()[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
inline const JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
 | 
			
		||||
    size_t index) const {
 | 
			
		||||
  return impl()->template as<JsonArray>()[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace ArduinoJson
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										77
									
								
								src/ArduinoJson/JsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										77
									
								
								src/ArduinoJson/JsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>  // for size_t
 | 
			
		||||
#include <stdint.h>  // for uint8_t
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "Data/NonCopyable.hpp"
 | 
			
		||||
#include "JsonVariant.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "TypeTraits/IsArray.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonObject;
 | 
			
		||||
 | 
			
		||||
// Entry point for using the library.
 | 
			
		||||
//
 | 
			
		||||
// Handle the memory management (done in derived classes) and calls the parser.
 | 
			
		||||
// This abstract class is implemented by StaticJsonBuffer which implements a
 | 
			
		||||
// fixed memory allocation.
 | 
			
		||||
class JsonBuffer : Internals::NonCopyable {
 | 
			
		||||
 public:
 | 
			
		||||
  // Allocates an empty JsonArray.
 | 
			
		||||
  //
 | 
			
		||||
  // Returns a reference to the new JsonArray or JsonArray::invalid() if the
 | 
			
		||||
  // allocation fails.
 | 
			
		||||
  JsonArray &createArray();
 | 
			
		||||
 | 
			
		||||
  // Allocates an empty JsonObject.
 | 
			
		||||
  //
 | 
			
		||||
  // Returns a reference to the new JsonObject or JsonObject::invalid() if the
 | 
			
		||||
  // allocation fails.
 | 
			
		||||
  JsonObject &createObject();
 | 
			
		||||
 | 
			
		||||
  // Duplicates a string
 | 
			
		||||
  //
 | 
			
		||||
  // char* strdup(TValue);
 | 
			
		||||
  // TValue = const std::string&, const String&,
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                char *>::type
 | 
			
		||||
  strdup(const TString &src) {
 | 
			
		||||
    return Internals::StringTraits<TString>::duplicate(src, this);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // char* strdup(TValue);
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  char *strdup(const TString *src) {
 | 
			
		||||
    return Internals::StringTraits<const TString *>::duplicate(src, this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocates n bytes in the JsonBuffer.
 | 
			
		||||
  // Return a pointer to the allocated memory or NULL if allocation fails.
 | 
			
		||||
  virtual void *alloc(size_t size) = 0;
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  // CAUTION: NO VIRTUAL DESTRUCTOR!
 | 
			
		||||
  // If we add a virtual constructor the Arduino compiler will add malloc()
 | 
			
		||||
  // and free() to the binary, adding 706 useless bytes.
 | 
			
		||||
  ~JsonBuffer() {}
 | 
			
		||||
 | 
			
		||||
  // Preserve aligment if necessary
 | 
			
		||||
  static FORCE_INLINE size_t round_size_up(size_t bytes) {
 | 
			
		||||
#if ARDUINOJSON_ENABLE_ALIGNMENT
 | 
			
		||||
    const size_t x = sizeof(void *) - 1;
 | 
			
		||||
    return (bytes + x) & ~x;
 | 
			
		||||
#else
 | 
			
		||||
    return bytes;
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										125
									
								
								src/ArduinoJson/JsonBufferBase.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										125
									
								
								src/ArduinoJson/JsonBufferBase.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Deserialization/JsonParser.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
template <typename TDerived>
 | 
			
		||||
class JsonBufferBase : public JsonBuffer {
 | 
			
		||||
 public:
 | 
			
		||||
  // Allocates and populate a JsonArray from a JSON string.
 | 
			
		||||
  //
 | 
			
		||||
  // The First argument is a pointer to the JSON string, the memory must be
 | 
			
		||||
  // writable
 | 
			
		||||
  // because the parser will insert null-terminators and replace escaped chars.
 | 
			
		||||
  //
 | 
			
		||||
  // The second argument set the nesting limit
 | 
			
		||||
  //
 | 
			
		||||
  // Returns a reference to the new JsonObject or JsonObject::invalid() if the
 | 
			
		||||
  // allocation fails.
 | 
			
		||||
  // With this overload, the JsonBuffer will make a copy of the string
 | 
			
		||||
  //
 | 
			
		||||
  // JsonArray& parseArray(TString);
 | 
			
		||||
  // TString = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonArray &>::type
 | 
			
		||||
  parseArray(const TString &json,
 | 
			
		||||
             uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseArray();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonArray& parseArray(TString);
 | 
			
		||||
  // TString = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonArray &parseArray(
 | 
			
		||||
      TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseArray();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonArray& parseArray(TString);
 | 
			
		||||
  // TString = std::istream&, Stream&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonArray &parseArray(
 | 
			
		||||
      TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseArray();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocates and populate a JsonObject from a JSON string.
 | 
			
		||||
  //
 | 
			
		||||
  // The First argument is a pointer to the JSON string, the memory must be
 | 
			
		||||
  // writable
 | 
			
		||||
  // because the parser will insert null-terminators and replace escaped chars.
 | 
			
		||||
  //
 | 
			
		||||
  // The second argument set the nesting limit
 | 
			
		||||
  //
 | 
			
		||||
  // Returns a reference to the new JsonObject or JsonObject::invalid() if the
 | 
			
		||||
  // allocation fails.
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& parseObject(TString);
 | 
			
		||||
  // TString = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonObject &>::type
 | 
			
		||||
  parseObject(const TString &json,
 | 
			
		||||
              uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseObject();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& parseObject(TString);
 | 
			
		||||
  // TString = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonObject &parseObject(
 | 
			
		||||
      TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseObject();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& parseObject(TString);
 | 
			
		||||
  // TString = std::istream&, Stream&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonObject &parseObject(
 | 
			
		||||
      TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseObject();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Generalized version of parseArray() and parseObject(), also works for
 | 
			
		||||
  // integral types.
 | 
			
		||||
  //
 | 
			
		||||
  // JsonVariant parse(TString);
 | 
			
		||||
  // TString = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonVariant>::type
 | 
			
		||||
  parse(const TString &json,
 | 
			
		||||
        uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseVariant();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonVariant parse(TString);
 | 
			
		||||
  // TString = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonVariant parse(TString *json,
 | 
			
		||||
                    uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseVariant();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonVariant parse(TString);
 | 
			
		||||
  // TString = std::istream&, Stream&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonVariant parse(TString &json,
 | 
			
		||||
                    uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
 | 
			
		||||
    return Internals::makeParser(that(), json, nestingLimit).parseVariant();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  ~JsonBufferBase() {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  TDerived *that() {
 | 
			
		||||
    return static_cast<TDerived *>(this);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/ArduinoJson/JsonBufferImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								src/ArduinoJson/JsonBufferImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Deserialization/JsonParser.hpp"
 | 
			
		||||
 | 
			
		||||
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
 | 
			
		||||
  JsonArray *ptr = new (this) JsonArray(this);
 | 
			
		||||
  return ptr ? *ptr : JsonArray::invalid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
 | 
			
		||||
  JsonObject *ptr = new (this) JsonObject(this);
 | 
			
		||||
  return ptr ? *ptr : JsonObject::invalid();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										348
									
								
								src/ArduinoJson/JsonObject.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										348
									
								
								src/ArduinoJson/JsonObject.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,348 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonBufferAllocated.hpp"
 | 
			
		||||
#include "Data/List.hpp"
 | 
			
		||||
#include "Data/ReferenceType.hpp"
 | 
			
		||||
#include "Data/ValueSetter.hpp"
 | 
			
		||||
#include "JsonPair.hpp"
 | 
			
		||||
#include "Serialization/JsonPrintable.hpp"
 | 
			
		||||
#include "StringTraits/StringTraits.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "TypeTraits/IsArray.hpp"
 | 
			
		||||
#include "TypeTraits/IsFloatingPoint.hpp"
 | 
			
		||||
#include "TypeTraits/IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
// Returns the size (in bytes) of an object with n elements.
 | 
			
		||||
// Can be very handy to determine the size of a StaticJsonBuffer.
 | 
			
		||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
 | 
			
		||||
  (sizeof(JsonObject) + (NUMBER_OF_ELEMENTS) * sizeof(JsonObject::node_type))
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// Forward declarations
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonBuffer;
 | 
			
		||||
 | 
			
		||||
// A dictionary of JsonVariant indexed by string (char*)
 | 
			
		||||
//
 | 
			
		||||
// The constructor is private, instances must be created via
 | 
			
		||||
// JsonBuffer::createObject() or JsonBuffer::parseObject().
 | 
			
		||||
// A JsonObject can be serialized to a JSON string via JsonObject::printTo().
 | 
			
		||||
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
 | 
			
		||||
class JsonObject : public Internals::JsonPrintable<JsonObject>,
 | 
			
		||||
                   public Internals::ReferenceType,
 | 
			
		||||
                   public Internals::NonCopyable,
 | 
			
		||||
                   public Internals::List<JsonPair>,
 | 
			
		||||
                   public Internals::JsonBufferAllocated {
 | 
			
		||||
 public:
 | 
			
		||||
  // Create an empty JsonArray attached to the specified JsonBuffer.
 | 
			
		||||
  // You should not use this constructor directly.
 | 
			
		||||
  // Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject().
 | 
			
		||||
  explicit JsonObject(JsonBuffer* buffer) throw()
 | 
			
		||||
      : Internals::List<JsonPair>(buffer) {}
 | 
			
		||||
 | 
			
		||||
  // Gets or sets the value associated with the specified key.
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObjectSubscript operator[](TKey)
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonObjectSubscript<const TString&> >::type
 | 
			
		||||
  operator[](const TString& key) {
 | 
			
		||||
    return JsonObjectSubscript<const TString&>(*this, key);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObjectSubscript operator[](TKey)
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonObjectSubscript<const TString*> operator[](const TString* key) {
 | 
			
		||||
    return JsonObjectSubscript<const TString*>(*this, key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the value associated with the specified key.
 | 
			
		||||
  //
 | 
			
		||||
  // const JsonObjectSubscript operator[](TKey) const;
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      !TypeTraits::IsArray<TString>::value,
 | 
			
		||||
      const JsonObjectSubscript<const TString&> >::type
 | 
			
		||||
  operator[](const TString& key) const {
 | 
			
		||||
    return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this),
 | 
			
		||||
                                               key);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // const JsonObjectSubscript operator[](TKey) const;
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  const JsonObjectSubscript<const TString*> operator[](
 | 
			
		||||
      const TString* key) const {
 | 
			
		||||
    return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this),
 | 
			
		||||
                                               key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Sets the specified key with the specified value.
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value &&
 | 
			
		||||
                                    !TypeTraits::IsArray<TValue>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  set(const TString& key, const TValue& value) {
 | 
			
		||||
    return set_impl<const TString&, const TValue&>(key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  set(const TString& key, const TValue* value) {
 | 
			
		||||
    return set_impl<const TString&, const TValue*>(key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  // TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, bool>::type
 | 
			
		||||
  set(const TString* key, const TValue& value) {
 | 
			
		||||
    return set_impl<const TString*, const TValue&>(key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  bool set(const TString* key, const TValue* value) {
 | 
			
		||||
    return set_impl<const TString*, const TValue*>(key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue, uint8_t decimals);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value &&
 | 
			
		||||
                                    !TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
      set(const TString& key, TValue value, uint8_t) {
 | 
			
		||||
    return set_impl<const TString&, const JsonVariant&>(key,
 | 
			
		||||
                                                        JsonVariant(value));
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TKey, TValue, uint8_t decimals);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
      set(const TString* key, TValue value, uint8_t) {
 | 
			
		||||
    return set_impl<const TString*, const JsonVariant&>(key,
 | 
			
		||||
                                                        JsonVariant(value));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the value associated with the specified key.
 | 
			
		||||
  //
 | 
			
		||||
  // TValue get<TValue>(TKey);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      !TypeTraits::IsArray<TString>::value,
 | 
			
		||||
      typename Internals::JsonVariantAs<TValue>::type>::type
 | 
			
		||||
  get(const TString& key) const {
 | 
			
		||||
    return get_impl<const TString&, TValue>(key);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // TValue get<TValue>(TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename Internals::JsonVariantAs<TValue>::type get(
 | 
			
		||||
      const TString* key) const {
 | 
			
		||||
    return get_impl<const TString*, TValue>(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Checks the type of the value associated with the specified key.
 | 
			
		||||
  //
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<TValue>(TKey) const;
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  is(const TString& key) const {
 | 
			
		||||
    return is_impl<const TString&, TValue>(key);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<TValue>(TKey) const;
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue, typename TString>
 | 
			
		||||
  bool is(const TString* key) const {
 | 
			
		||||
    return is_impl<const TString*, TValue>(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Creates and adds a JsonArray.
 | 
			
		||||
  //
 | 
			
		||||
  // JsonArray& createNestedArray(TKey);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonArray&>::type
 | 
			
		||||
  createNestedArray(const TString& key) {
 | 
			
		||||
    return createNestedArray_impl<const TString&>(key);
 | 
			
		||||
  }
 | 
			
		||||
  // JsonArray& createNestedArray(TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonArray& createNestedArray(const TString* key) {
 | 
			
		||||
    return createNestedArray_impl<const TString*>(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Creates and adds a JsonObject.
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& createNestedObject(TKey);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                JsonObject&>::type
 | 
			
		||||
  createNestedObject(const TString& key) {
 | 
			
		||||
    return createNestedObject_impl<const TString&>(key);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& createNestedObject(TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  JsonObject& createNestedObject(const TString* key) {
 | 
			
		||||
    return createNestedObject_impl<const TString*>(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Tells weither the specified key is present and associated with a value.
 | 
			
		||||
  //
 | 
			
		||||
  // bool containsKey(TKey);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  containsKey(const TString& key) const {
 | 
			
		||||
    return findKey<const TString&>(key) != end();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool containsKey(TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  bool containsKey(const TString* key) const {
 | 
			
		||||
    return findKey<const TString*>(key) != end();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Removes the specified key and the associated value.
 | 
			
		||||
  //
 | 
			
		||||
  // void remove(TKey);
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
 | 
			
		||||
                                void>::type
 | 
			
		||||
  remove(const TString& key) {
 | 
			
		||||
    remove(findKey<const TString&>(key));
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // void remove(TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  void remove(const TString* key) {
 | 
			
		||||
    remove(findKey<const TString*>(key));
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // void remove(iterator)
 | 
			
		||||
  using Internals::List<JsonPair>::remove;
 | 
			
		||||
 | 
			
		||||
  // Returns a reference an invalid JsonObject.
 | 
			
		||||
  // This object is meant to replace a NULL pointer.
 | 
			
		||||
  // This is used when memory allocation or JSON parsing fail.
 | 
			
		||||
  static JsonObject& invalid() {
 | 
			
		||||
    static JsonObject instance(NULL);
 | 
			
		||||
    return instance;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // Returns the list node that matches the specified key.
 | 
			
		||||
  template <typename TStringRef>
 | 
			
		||||
  iterator findKey(TStringRef key) {
 | 
			
		||||
    iterator it;
 | 
			
		||||
    for (it = begin(); it != end(); ++it) {
 | 
			
		||||
      if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
 | 
			
		||||
    }
 | 
			
		||||
    return it;
 | 
			
		||||
  }
 | 
			
		||||
  template <typename TStringRef>
 | 
			
		||||
  const_iterator findKey(TStringRef key) const {
 | 
			
		||||
    return const_cast<JsonObject*>(this)->findKey<TStringRef>(key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TStringRef, typename TValue>
 | 
			
		||||
  typename Internals::JsonVariantAs<TValue>::type get_impl(
 | 
			
		||||
      TStringRef key) const {
 | 
			
		||||
    const_iterator it = findKey<TStringRef>(key);
 | 
			
		||||
    return it != end() ? it->value.as<TValue>()
 | 
			
		||||
                       : Internals::JsonVariantDefault<TValue>::get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TStringRef, typename TValueRef>
 | 
			
		||||
  bool set_impl(TStringRef key, TValueRef value) {
 | 
			
		||||
    iterator it = findKey<TStringRef>(key);
 | 
			
		||||
    if (it == end()) {
 | 
			
		||||
      it = Internals::List<JsonPair>::add();
 | 
			
		||||
      if (it == end()) return false;
 | 
			
		||||
 | 
			
		||||
      bool key_ok =
 | 
			
		||||
          Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
 | 
			
		||||
      if (!key_ok) return false;
 | 
			
		||||
    }
 | 
			
		||||
    return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TStringRef, typename TValue>
 | 
			
		||||
  bool is_impl(TStringRef key) const {
 | 
			
		||||
    const_iterator it = findKey<TStringRef>(key);
 | 
			
		||||
    return it != end() ? it->value.is<TValue>() : false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TStringRef>
 | 
			
		||||
  JsonArray& createNestedArray_impl(TStringRef key);
 | 
			
		||||
 | 
			
		||||
  template <typename TStringRef>
 | 
			
		||||
  JsonObject& createNestedObject_impl(TStringRef key);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
namespace Internals {
 | 
			
		||||
template <>
 | 
			
		||||
struct JsonVariantDefault<JsonObject> {
 | 
			
		||||
  static JsonObject& get() {
 | 
			
		||||
    return JsonObject::invalid();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/ArduinoJson/JsonObjectImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								src/ArduinoJson/JsonObjectImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonArray.hpp"
 | 
			
		||||
#include "JsonObject.hpp"
 | 
			
		||||
#include "JsonObjectSubscript.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TStringRef>
 | 
			
		||||
inline JsonArray &JsonObject::createNestedArray_impl(TStringRef key) {
 | 
			
		||||
  if (!_buffer) return JsonArray::invalid();
 | 
			
		||||
  JsonArray &array = _buffer->createArray();
 | 
			
		||||
  set(key, array);
 | 
			
		||||
  return array;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename TStringRef>
 | 
			
		||||
inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) {
 | 
			
		||||
  if (!_buffer) return JsonObject::invalid();
 | 
			
		||||
  JsonObject &object = _buffer->createObject();
 | 
			
		||||
  set(key, object);
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								src/ArduinoJson/JsonObjectSubscript.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										114
									
								
								src/ArduinoJson/JsonObjectSubscript.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Configuration.hpp"
 | 
			
		||||
#include "JsonVariantBase.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(push)
 | 
			
		||||
#pragma warning(disable : 4522)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TStringRef>
 | 
			
		||||
class JsonObjectSubscript
 | 
			
		||||
    : public JsonVariantBase<JsonObjectSubscript<TStringRef> > {
 | 
			
		||||
  typedef JsonObjectSubscript<TStringRef> this_type;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  FORCE_INLINE JsonObjectSubscript(JsonObject& object, TStringRef key)
 | 
			
		||||
      : _object(object), _key(key) {}
 | 
			
		||||
 | 
			
		||||
  FORCE_INLINE this_type& operator=(const this_type& src) {
 | 
			
		||||
    _object.set(_key, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the specified value
 | 
			
		||||
  //
 | 
			
		||||
  // operator=(TValue);
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE
 | 
			
		||||
      typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
 | 
			
		||||
                                    this_type&>::type
 | 
			
		||||
      operator=(const TValue& src) {
 | 
			
		||||
    _object.set(_key, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // operator=(TValue);
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE this_type& operator=(const TValue* src) {
 | 
			
		||||
    _object.set(_key, src);
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FORCE_INLINE bool success() const {
 | 
			
		||||
    return _object.containsKey(_key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const {
 | 
			
		||||
    return _object.get<TValue>(_key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE bool is() const {
 | 
			
		||||
    return _object.is<TValue>(_key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Sets the specified value.
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue);
 | 
			
		||||
  // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant,
 | 
			
		||||
  //          const std::string&, const String&,
 | 
			
		||||
  //          const JsonArray&, const JsonObject&
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE
 | 
			
		||||
      typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
 | 
			
		||||
                                    bool>::type
 | 
			
		||||
      set(const TValue& value) {
 | 
			
		||||
    return _object.set(_key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue);
 | 
			
		||||
  // TValue = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  FORCE_INLINE bool set(const TValue* value) {
 | 
			
		||||
    return _object.set(_key, value);
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool set(TValue, uint8_t decimals);
 | 
			
		||||
  // TValue = float, double
 | 
			
		||||
  template <typename TValue>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  FORCE_INLINE bool set(const TValue& value, uint8_t) {
 | 
			
		||||
    return _object.set(_key, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  JsonObject& _object;
 | 
			
		||||
  TStringRef _key;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
template <typename TStringRef>
 | 
			
		||||
inline std::ostream& operator<<(std::ostream& os,
 | 
			
		||||
                                const JsonObjectSubscript<TStringRef>& source) {
 | 
			
		||||
  return source.printTo(os);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
}  // namespace ArduinoJson
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#pragma warning(pop)
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										16
									
								
								src/ArduinoJson/JsonPair.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										16
									
								
								src/ArduinoJson/JsonPair.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonVariant.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// A key value pair for JsonObject.
 | 
			
		||||
struct JsonPair {
 | 
			
		||||
  const char* key;
 | 
			
		||||
  JsonVariant value;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										357
									
								
								src/ArduinoJson/JsonVariant.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										357
									
								
								src/ArduinoJson/JsonVariant.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,357 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>  // for uint8_t
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonVariantContent.hpp"
 | 
			
		||||
#include "Data/JsonVariantDefault.hpp"
 | 
			
		||||
#include "Data/JsonVariantType.hpp"
 | 
			
		||||
#include "JsonVariantBase.hpp"
 | 
			
		||||
#include "RawJson.hpp"
 | 
			
		||||
#include "Serialization/JsonPrintable.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "TypeTraits/IsChar.hpp"
 | 
			
		||||
#include "TypeTraits/IsFloatingPoint.hpp"
 | 
			
		||||
#include "TypeTraits/IsIntegral.hpp"
 | 
			
		||||
#include "TypeTraits/IsSame.hpp"
 | 
			
		||||
#include "TypeTraits/IsSignedIntegral.hpp"
 | 
			
		||||
#include "TypeTraits/IsUnsignedIntegral.hpp"
 | 
			
		||||
#include "TypeTraits/RemoveConst.hpp"
 | 
			
		||||
#include "TypeTraits/RemoveReference.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// Forward declarations.
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonObject;
 | 
			
		||||
 | 
			
		||||
// A variant that can be a any value serializable to a JSON value.
 | 
			
		||||
//
 | 
			
		||||
// It can be set to:
 | 
			
		||||
// - a boolean
 | 
			
		||||
// - a char, short, int or a long (signed or unsigned)
 | 
			
		||||
// - a string (const char*)
 | 
			
		||||
// - a reference to a JsonArray or JsonObject
 | 
			
		||||
class JsonVariant : public JsonVariantBase<JsonVariant> {
 | 
			
		||||
  template <typename Print>
 | 
			
		||||
  friend class Internals::JsonSerializer;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  // Creates an uninitialized JsonVariant
 | 
			
		||||
  JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing a boolean value.
 | 
			
		||||
  // It will be serialized as "true" or "false" in JSON.
 | 
			
		||||
  JsonVariant(bool value) {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    _type = JSON_BOOLEAN;
 | 
			
		||||
    _content.asInteger = static_cast<JsonUInt>(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing a floating point value.
 | 
			
		||||
  // JsonVariant(double value);
 | 
			
		||||
  // JsonVariant(float value);
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  JsonVariant(T value, typename TypeTraits::EnableIf<
 | 
			
		||||
                           TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    _type = JSON_FLOAT;
 | 
			
		||||
    _content.asFloat = static_cast<JsonFloat>(value);
 | 
			
		||||
  }
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  DEPRECATED("Second argument is not supported anymore")
 | 
			
		||||
  JsonVariant(T value, uint8_t,
 | 
			
		||||
              typename TypeTraits::EnableIf<
 | 
			
		||||
                  TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    _type = JSON_FLOAT;
 | 
			
		||||
    _content.asFloat = static_cast<JsonFloat>(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing an integer value.
 | 
			
		||||
  // JsonVariant(char)
 | 
			
		||||
  // JsonVariant(signed short)
 | 
			
		||||
  // JsonVariant(signed int)
 | 
			
		||||
  // JsonVariant(signed long)
 | 
			
		||||
  // JsonVariant(signed char)
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  JsonVariant(T value, typename TypeTraits::EnableIf<
 | 
			
		||||
                           TypeTraits::IsSignedIntegral<T>::value ||
 | 
			
		||||
                           TypeTraits::IsSame<T, char>::value>::type * = 0) {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    if (value >= 0) {
 | 
			
		||||
      _type = JSON_POSITIVE_INTEGER;
 | 
			
		||||
      _content.asInteger = static_cast<JsonUInt>(value);
 | 
			
		||||
    } else {
 | 
			
		||||
      _type = JSON_NEGATIVE_INTEGER;
 | 
			
		||||
      _content.asInteger = static_cast<JsonUInt>(-value);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // JsonVariant(unsigned short)
 | 
			
		||||
  // JsonVariant(unsigned int)
 | 
			
		||||
  // JsonVariant(unsigned long)
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  JsonVariant(T value,
 | 
			
		||||
              typename TypeTraits::EnableIf<
 | 
			
		||||
                  TypeTraits::IsUnsignedIntegral<T>::value>::type * = 0) {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    _type = JSON_POSITIVE_INTEGER;
 | 
			
		||||
    _content.asInteger = static_cast<JsonUInt>(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing a string.
 | 
			
		||||
  // JsonVariant(const char*);
 | 
			
		||||
  // JsonVariant(const signed char*);
 | 
			
		||||
  // JsonVariant(const unsigned char*);
 | 
			
		||||
  template <typename TChar>
 | 
			
		||||
  JsonVariant(
 | 
			
		||||
      const TChar *value,
 | 
			
		||||
      typename TypeTraits::EnableIf<TypeTraits::IsChar<TChar>::value>::type * =
 | 
			
		||||
          0) {
 | 
			
		||||
    _type = Internals::JSON_STRING;
 | 
			
		||||
    _content.asString = reinterpret_cast<const char *>(value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing an unparsed string
 | 
			
		||||
  JsonVariant(RawJson value) {
 | 
			
		||||
    _type = Internals::JSON_UNPARSED;
 | 
			
		||||
    _content.asString = value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing a reference to an array.
 | 
			
		||||
  // CAUTION: we are lying about constness, because the array can be modified if
 | 
			
		||||
  // the variant is converted back to a JsonArray&
 | 
			
		||||
  JsonVariant(const JsonArray &array);
 | 
			
		||||
 | 
			
		||||
  // Create a JsonVariant containing a reference to an object.
 | 
			
		||||
  // CAUTION: we are lying about constness, because the object can be modified
 | 
			
		||||
  // if the variant is converted back to a JsonObject&
 | 
			
		||||
  JsonVariant(const JsonObject &object);
 | 
			
		||||
 | 
			
		||||
  // Get the variant as the specified type.
 | 
			
		||||
  //
 | 
			
		||||
  // char as<char>() const;
 | 
			
		||||
  // signed char as<signed char>() const;
 | 
			
		||||
  // signed short as<signed short>() const;
 | 
			
		||||
  // signed int as<signed int>() const;
 | 
			
		||||
  // signed long as<signed long>() const;
 | 
			
		||||
  // unsigned char as<unsigned char>() const;
 | 
			
		||||
  // unsigned short as<unsigned short>() const;
 | 
			
		||||
  // unsigned int as<unsigned int>() const;
 | 
			
		||||
  // unsigned long as<unsigned long>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, T>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsInteger<T>();
 | 
			
		||||
  }
 | 
			
		||||
  // bool as<bool>() const
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
 | 
			
		||||
                                      T>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsInteger<int>() != 0;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // double as<double>() const;
 | 
			
		||||
  // float as<float>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
 | 
			
		||||
                                      T>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsFloat<T>();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // const char* as<const char*>() const;
 | 
			
		||||
  // const char* as<char*>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
 | 
			
		||||
                                    TypeTraits::IsSame<T, char *>::value,
 | 
			
		||||
                                const char *>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsString();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // std::string as<std::string>() const;
 | 
			
		||||
  // String as<String>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<Internals::StringTraits<T>::has_append, T>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    const char *cstr = variantAsString();
 | 
			
		||||
    if (cstr) return T(cstr);
 | 
			
		||||
    T s;
 | 
			
		||||
    printTo(s);
 | 
			
		||||
    return s;
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonArray& as<JsonArray> const;
 | 
			
		||||
  // JsonArray& as<JsonArray&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
 | 
			
		||||
                         JsonArray>::value,
 | 
			
		||||
      JsonArray &>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsArray();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // const JsonArray& as<const JsonArray&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
 | 
			
		||||
                         const JsonArray>::value,
 | 
			
		||||
      const JsonArray &>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsArray();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& as<JsonObject> const;
 | 
			
		||||
  // JsonObject& as<JsonObject&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
 | 
			
		||||
                         JsonObject>::value,
 | 
			
		||||
      JsonObject &>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsObject();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObject& as<const JsonObject> const;
 | 
			
		||||
  // JsonObject& as<const JsonObject&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
 | 
			
		||||
                         const JsonObject>::value,
 | 
			
		||||
      const JsonObject &>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return variantAsObject();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonVariant as<JsonVariant> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsSame<T, JsonVariant>::value,
 | 
			
		||||
                                T>::type
 | 
			
		||||
  as() const {
 | 
			
		||||
    return *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Tells weither the variant has the specified type.
 | 
			
		||||
  // Returns true if the variant has type type T, false otherwise.
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<char>() const;
 | 
			
		||||
  // bool is<signed char>() const;
 | 
			
		||||
  // bool is<signed short>() const;
 | 
			
		||||
  // bool is<signed int>() const;
 | 
			
		||||
  // bool is<signed long>() const;
 | 
			
		||||
  // bool is<unsigned char>() const;
 | 
			
		||||
  // bool is<unsigned short>() const;
 | 
			
		||||
  // bool is<unsigned int>() const;
 | 
			
		||||
  // bool is<unsigned long>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsInteger();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<double>() const;
 | 
			
		||||
  // bool is<float>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsFloat();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<bool>() const
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value, bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsBoolean();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<const char*>() const;
 | 
			
		||||
  // bool is<char*>() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
 | 
			
		||||
                                    TypeTraits::IsSame<T, char *>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsString();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<JsonArray> const;
 | 
			
		||||
  // bool is<JsonArray&> const;
 | 
			
		||||
  // bool is<const JsonArray&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<
 | 
			
		||||
          typename TypeTraits::RemoveConst<
 | 
			
		||||
              typename TypeTraits::RemoveReference<T>::type>::type,
 | 
			
		||||
          JsonArray>::value,
 | 
			
		||||
      bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsArray();
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // bool is<JsonObject> const;
 | 
			
		||||
  // bool is<JsonObject&> const;
 | 
			
		||||
  // bool is<const JsonObject&> const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  typename TypeTraits::EnableIf<
 | 
			
		||||
      TypeTraits::IsSame<
 | 
			
		||||
          typename TypeTraits::RemoveConst<
 | 
			
		||||
              typename TypeTraits::RemoveReference<T>::type>::type,
 | 
			
		||||
          JsonObject>::value,
 | 
			
		||||
      bool>::type
 | 
			
		||||
  is() const {
 | 
			
		||||
    return variantIsObject();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns true if the variant has a value
 | 
			
		||||
  bool success() const {
 | 
			
		||||
    return _type != Internals::JSON_UNDEFINED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  JsonArray &variantAsArray() const;
 | 
			
		||||
  JsonObject &variantAsObject() const;
 | 
			
		||||
  const char *variantAsString() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  T variantAsFloat() const;
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  T variantAsInteger() const;
 | 
			
		||||
  bool variantIsBoolean() const;
 | 
			
		||||
  bool variantIsFloat() const;
 | 
			
		||||
  bool variantIsInteger() const;
 | 
			
		||||
  bool variantIsArray() const {
 | 
			
		||||
    return _type == Internals::JSON_ARRAY;
 | 
			
		||||
  }
 | 
			
		||||
  bool variantIsObject() const {
 | 
			
		||||
    return _type == Internals::JSON_OBJECT;
 | 
			
		||||
  }
 | 
			
		||||
  bool variantIsString() const {
 | 
			
		||||
    return _type == Internals::JSON_STRING ||
 | 
			
		||||
           (_type == Internals::JSON_UNPARSED && _content.asString &&
 | 
			
		||||
            !strcmp("null", _content.asString));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // The current type of the variant
 | 
			
		||||
  Internals::JsonVariantType _type;
 | 
			
		||||
 | 
			
		||||
  // The various alternatives for the value of the variant.
 | 
			
		||||
  Internals::JsonVariantContent _content;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DEPRECATED("Decimal places are ignored, use the float value instead")
 | 
			
		||||
inline JsonVariant float_with_n_digits(float value, uint8_t) {
 | 
			
		||||
  return JsonVariant(value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DEPRECATED("Decimal places are ignored, use the double value instead")
 | 
			
		||||
inline JsonVariant double_with_n_digits(double value, uint8_t) {
 | 
			
		||||
  return JsonVariant(value);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/ArduinoJson/JsonVariantBase.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								src/ArduinoJson/JsonVariantBase.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonVariantCasts.hpp"
 | 
			
		||||
#include "JsonVariantComparisons.hpp"
 | 
			
		||||
#include "JsonVariantOr.hpp"
 | 
			
		||||
#include "JsonVariantSubscripts.hpp"
 | 
			
		||||
#include "Serialization/JsonPrintable.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
class JsonVariantBase : public Internals::JsonPrintable<TImpl>,
 | 
			
		||||
                        public JsonVariantCasts<TImpl>,
 | 
			
		||||
                        public JsonVariantComparisons<TImpl>,
 | 
			
		||||
                        public JsonVariantOr<TImpl>,
 | 
			
		||||
                        public JsonVariantSubscripts<TImpl>,
 | 
			
		||||
                        public TypeTraits::JsonVariantTag {};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								src/ArduinoJson/JsonVariantCasts.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										57
									
								
								src/ArduinoJson/JsonVariantCasts.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonVariantAs.hpp"
 | 
			
		||||
#include "Polyfills/attributes.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
class JsonVariantCasts {
 | 
			
		||||
 public:
 | 
			
		||||
#if ARDUINOJSON_ENABLE_DEPRECATED
 | 
			
		||||
  DEPRECATED("use as<JsonArray>() instead")
 | 
			
		||||
  FORCE_INLINE JsonArray &asArray() const {
 | 
			
		||||
    return impl()->template as<JsonArray>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DEPRECATED("use as<JsonObject>() instead")
 | 
			
		||||
  FORCE_INLINE JsonObject &asObject() const {
 | 
			
		||||
    return impl()->template as<JsonObject>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DEPRECATED("use as<char*>() instead")
 | 
			
		||||
  FORCE_INLINE const char *asString() const {
 | 
			
		||||
    return impl()->template as<const char *>();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // Gets the variant as an array.
 | 
			
		||||
  // Returns a reference to the JsonArray or JsonArray::invalid() if the
 | 
			
		||||
  // variant
 | 
			
		||||
  // is not an array.
 | 
			
		||||
  FORCE_INLINE operator JsonArray &() const {
 | 
			
		||||
    return impl()->template as<JsonArray &>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the variant as an object.
 | 
			
		||||
  // Returns a reference to the JsonObject or JsonObject::invalid() if the
 | 
			
		||||
  // variant is not an object.
 | 
			
		||||
  FORCE_INLINE operator JsonObject &() const {
 | 
			
		||||
    return impl()->template as<JsonObject &>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  FORCE_INLINE operator T() const {
 | 
			
		||||
    return impl()->template as<T>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const TImpl *impl() const {
 | 
			
		||||
    return static_cast<const TImpl *>(this);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										141
									
								
								src/ArduinoJson/JsonVariantComparisons.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										141
									
								
								src/ArduinoJson/JsonVariantComparisons.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "StringTraits/StringTraits.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "TypeTraits/IsVariant.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
class JsonVariantComparisons {
 | 
			
		||||
 public:
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator==(const JsonVariantComparisons &variant,
 | 
			
		||||
                         TComparand comparand) {
 | 
			
		||||
    return variant.equals(comparand);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend
 | 
			
		||||
      typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
 | 
			
		||||
                                    bool>::type
 | 
			
		||||
      operator==(TComparand comparand, const JsonVariantComparisons &variant) {
 | 
			
		||||
    return variant.equals(comparand);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator!=(const JsonVariantComparisons &variant,
 | 
			
		||||
                         TComparand comparand) {
 | 
			
		||||
    return !variant.equals(comparand);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend
 | 
			
		||||
      typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
 | 
			
		||||
                                    bool>::type
 | 
			
		||||
      operator!=(TComparand comparand, const JsonVariantComparisons &variant) {
 | 
			
		||||
    return !variant.equals(comparand);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator<=(const JsonVariantComparisons &left, TComparand right) {
 | 
			
		||||
    return left.as<TComparand>() <= right;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator<=(TComparand comparand,
 | 
			
		||||
                         const JsonVariantComparisons &variant) {
 | 
			
		||||
    return comparand <= variant.as<TComparand>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator>=(const JsonVariantComparisons &variant,
 | 
			
		||||
                         TComparand comparand) {
 | 
			
		||||
    return variant.as<TComparand>() >= comparand;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator>=(TComparand comparand,
 | 
			
		||||
                         const JsonVariantComparisons &variant) {
 | 
			
		||||
    return comparand >= variant.as<TComparand>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator<(const JsonVariantComparisons &varian,
 | 
			
		||||
                        TComparand comparand) {
 | 
			
		||||
    return varian.as<TComparand>() < comparand;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator<(TComparand comparand,
 | 
			
		||||
                        const JsonVariantComparisons &variant) {
 | 
			
		||||
    return comparand < variant.as<TComparand>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator>(const JsonVariantComparisons &variant,
 | 
			
		||||
                        TComparand comparand) {
 | 
			
		||||
    return variant.as<TComparand>() > comparand;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  friend bool operator>(TComparand comparand,
 | 
			
		||||
                        const JsonVariantComparisons &variant) {
 | 
			
		||||
    return comparand > variant.as<TComparand>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const TImpl *impl() const {
 | 
			
		||||
    return static_cast<const TImpl *>(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  const typename Internals::JsonVariantAs<T>::type as() const {
 | 
			
		||||
    return impl()->template as<T>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  bool is() const {
 | 
			
		||||
    return impl()->template is<T>();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<TypeTraits::IsString<TString>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  equals(const TString &comparand) const {
 | 
			
		||||
    const char *value = as<const char *>();
 | 
			
		||||
    return Internals::StringTraits<TString>::equals(comparand, value);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TComparand>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value &&
 | 
			
		||||
                                    !TypeTraits::IsString<TComparand>::value,
 | 
			
		||||
                                bool>::type
 | 
			
		||||
  equals(const TComparand &comparand) const {
 | 
			
		||||
    return as<TComparand>() == comparand;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TVariant2>
 | 
			
		||||
  bool equals(const JsonVariantComparisons<TVariant2> &right) const {
 | 
			
		||||
    using namespace Internals;
 | 
			
		||||
    if (is<bool>() && right.template is<bool>())
 | 
			
		||||
      return as<bool>() == right.template as<bool>();
 | 
			
		||||
    if (is<JsonInteger>() && right.template is<JsonInteger>())
 | 
			
		||||
      return as<JsonInteger>() == right.template as<JsonInteger>();
 | 
			
		||||
    if (is<JsonFloat>() && right.template is<JsonFloat>())
 | 
			
		||||
      return as<JsonFloat>() == right.template as<JsonFloat>();
 | 
			
		||||
    if (is<JsonArray>() && right.template is<JsonArray>())
 | 
			
		||||
      return as<JsonArray>() == right.template as<JsonArray>();
 | 
			
		||||
    if (is<JsonObject>() && right.template is<JsonObject>())
 | 
			
		||||
      return as<JsonObject>() == right.template as<JsonObject>();
 | 
			
		||||
    if (is<char *>() && right.template is<char *>())
 | 
			
		||||
      return strcmp(as<char *>(), right.template as<char *>()) == 0;
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								src/ArduinoJson/JsonVariantImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										126
									
								
								src/ArduinoJson/JsonVariantImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Configuration.hpp"
 | 
			
		||||
#include "JsonArray.hpp"
 | 
			
		||||
#include "JsonObject.hpp"
 | 
			
		||||
#include "JsonVariant.hpp"
 | 
			
		||||
#include "Polyfills/isFloat.hpp"
 | 
			
		||||
#include "Polyfills/isInteger.hpp"
 | 
			
		||||
#include "Polyfills/parseFloat.hpp"
 | 
			
		||||
#include "Polyfills/parseInteger.hpp"
 | 
			
		||||
 | 
			
		||||
#include <string.h>  // for strcmp
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
inline JsonVariant::JsonVariant(const JsonArray &array) {
 | 
			
		||||
  if (array.success()) {
 | 
			
		||||
    _type = Internals::JSON_ARRAY;
 | 
			
		||||
    _content.asArray = const_cast<JsonArray *>(&array);
 | 
			
		||||
  } else {
 | 
			
		||||
    _type = Internals::JSON_UNDEFINED;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline JsonVariant::JsonVariant(const JsonObject &object) {
 | 
			
		||||
  if (object.success()) {
 | 
			
		||||
    _type = Internals::JSON_OBJECT;
 | 
			
		||||
    _content.asObject = const_cast<JsonObject *>(&object);
 | 
			
		||||
  } else {
 | 
			
		||||
    _type = Internals::JSON_UNDEFINED;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline JsonArray &JsonVariant::variantAsArray() const {
 | 
			
		||||
  if (_type == Internals::JSON_ARRAY) return *_content.asArray;
 | 
			
		||||
  return JsonArray::invalid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline JsonObject &JsonVariant::variantAsObject() const {
 | 
			
		||||
  if (_type == Internals::JSON_OBJECT) return *_content.asObject;
 | 
			
		||||
  return JsonObject::invalid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T JsonVariant::variantAsInteger() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
  switch (_type) {
 | 
			
		||||
    case JSON_UNDEFINED:
 | 
			
		||||
      return 0;
 | 
			
		||||
    case JSON_POSITIVE_INTEGER:
 | 
			
		||||
    case JSON_BOOLEAN:
 | 
			
		||||
      return T(_content.asInteger);
 | 
			
		||||
    case JSON_NEGATIVE_INTEGER:
 | 
			
		||||
      return T(~_content.asInteger + 1);
 | 
			
		||||
    case JSON_STRING:
 | 
			
		||||
    case JSON_UNPARSED:
 | 
			
		||||
      return Polyfills::parseInteger<T>(_content.asString);
 | 
			
		||||
    default:
 | 
			
		||||
      return T(_content.asFloat);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline const char *JsonVariant::variantAsString() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
  if (_type == JSON_UNPARSED && _content.asString &&
 | 
			
		||||
      !strcmp("null", _content.asString))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T JsonVariant::variantAsFloat() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
  switch (_type) {
 | 
			
		||||
    case JSON_UNDEFINED:
 | 
			
		||||
      return 0;
 | 
			
		||||
    case JSON_POSITIVE_INTEGER:
 | 
			
		||||
    case JSON_BOOLEAN:
 | 
			
		||||
      return static_cast<T>(_content.asInteger);
 | 
			
		||||
    case JSON_NEGATIVE_INTEGER:
 | 
			
		||||
      return -static_cast<T>(_content.asInteger);
 | 
			
		||||
    case JSON_STRING:
 | 
			
		||||
    case JSON_UNPARSED:
 | 
			
		||||
      return Polyfills::parseFloat<T>(_content.asString);
 | 
			
		||||
    default:
 | 
			
		||||
      return static_cast<T>(_content.asFloat);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool JsonVariant::variantIsBoolean() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
  if (_type == JSON_BOOLEAN) return true;
 | 
			
		||||
 | 
			
		||||
  if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
 | 
			
		||||
 | 
			
		||||
  return !strcmp(_content.asString, "true") ||
 | 
			
		||||
         !strcmp(_content.asString, "false");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool JsonVariant::variantIsInteger() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
 | 
			
		||||
  return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
 | 
			
		||||
         (_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool JsonVariant::variantIsFloat() const {
 | 
			
		||||
  using namespace Internals;
 | 
			
		||||
 | 
			
		||||
  return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER ||
 | 
			
		||||
         _type == JSON_NEGATIVE_INTEGER ||
 | 
			
		||||
         (_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
 | 
			
		||||
  return source.printTo(os);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}  // namespace ArduinoJson
 | 
			
		||||
							
								
								
									
										36
									
								
								src/ArduinoJson/JsonVariantOr.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								src/ArduinoJson/JsonVariantOr.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonVariantAs.hpp"
 | 
			
		||||
#include "Polyfills/attributes.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
class JsonVariantOr {
 | 
			
		||||
 public:
 | 
			
		||||
  // Returns the default value if the JsonVariant is undefined of incompatible
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  T operator|(const T &defaultValue) const {
 | 
			
		||||
    if (impl()->template is<T>())
 | 
			
		||||
      return impl()->template as<T>();
 | 
			
		||||
    else
 | 
			
		||||
      return defaultValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Returns the default value if the JsonVariant is undefined of incompatible
 | 
			
		||||
  // Special case for string: null is treated as undefined
 | 
			
		||||
  const char *operator|(const char *defaultValue) const {
 | 
			
		||||
    const char *value = impl()->template as<const char *>();
 | 
			
		||||
    return value ? value : defaultValue;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const TImpl *impl() const {
 | 
			
		||||
    return static_cast<const TImpl *>(this);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/ArduinoJson/JsonVariantSubscripts.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										86
									
								
								src/ArduinoJson/JsonVariantSubscripts.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "Data/JsonVariantAs.hpp"
 | 
			
		||||
#include "Polyfills/attributes.hpp"
 | 
			
		||||
#include "StringTraits/StringTraits.hpp"
 | 
			
		||||
#include "TypeTraits/EnableIf.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// Forward declarations.
 | 
			
		||||
class JsonArraySubscript;
 | 
			
		||||
template <typename TKey>
 | 
			
		||||
class JsonObjectSubscript;
 | 
			
		||||
 | 
			
		||||
template <typename TImpl>
 | 
			
		||||
class JsonVariantSubscripts {
 | 
			
		||||
 public:
 | 
			
		||||
  // Mimics an array or an object.
 | 
			
		||||
  // Returns the size of the array or object if the variant has that type.
 | 
			
		||||
  // Returns 0 if the variant is neither an array nor an object
 | 
			
		||||
  size_t size() const {
 | 
			
		||||
    return impl()->template as<JsonArray>().size() +
 | 
			
		||||
           impl()->template as<JsonObject>().size();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Mimics an array.
 | 
			
		||||
  // Returns the element at specified index if the variant is an array.
 | 
			
		||||
  // Returns JsonVariant::invalid() if the variant is not an array.
 | 
			
		||||
  FORCE_INLINE const JsonArraySubscript operator[](size_t index) const;
 | 
			
		||||
  FORCE_INLINE JsonArraySubscript operator[](size_t index);
 | 
			
		||||
 | 
			
		||||
  // Mimics an object.
 | 
			
		||||
  // Returns the value associated with the specified key if the variant is
 | 
			
		||||
  // an object.
 | 
			
		||||
  // Return JsonVariant::invalid() if the variant is not an object.
 | 
			
		||||
  //
 | 
			
		||||
  // const JsonObjectSubscript operator[](TKey) const;
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  FORCE_INLINE typename TypeTraits::EnableIf<
 | 
			
		||||
      Internals::StringTraits<TString>::has_equals,
 | 
			
		||||
      const JsonObjectSubscript<const TString &> >::type
 | 
			
		||||
  operator[](const TString &key) const {
 | 
			
		||||
    return impl()->template as<JsonObject>()[key];
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // const JsonObjectSubscript operator[](TKey) const;
 | 
			
		||||
  // TKey = const std::string&, const String&
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  FORCE_INLINE typename TypeTraits::EnableIf<
 | 
			
		||||
      Internals::StringTraits<TString>::has_equals,
 | 
			
		||||
      JsonObjectSubscript<const TString &> >::type
 | 
			
		||||
  operator[](const TString &key) {
 | 
			
		||||
    return impl()->template as<JsonObject>()[key];
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObjectSubscript operator[](TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  FORCE_INLINE typename TypeTraits::EnableIf<
 | 
			
		||||
      Internals::StringTraits<const TString *>::has_equals,
 | 
			
		||||
      JsonObjectSubscript<const TString *> >::type
 | 
			
		||||
  operator[](const TString *key) {
 | 
			
		||||
    return impl()->template as<JsonObject>()[key];
 | 
			
		||||
  }
 | 
			
		||||
  //
 | 
			
		||||
  // JsonObjectSubscript operator[](TKey);
 | 
			
		||||
  // TKey = const char*, const char[N], const FlashStringHelper*
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  FORCE_INLINE typename TypeTraits::EnableIf<
 | 
			
		||||
      Internals::StringTraits<TString *>::has_equals,
 | 
			
		||||
      const JsonObjectSubscript<const TString *> >::type
 | 
			
		||||
  operator[](const TString *key) const {
 | 
			
		||||
    return impl()->template as<JsonObject>()[key];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const TImpl *impl() const {
 | 
			
		||||
    return static_cast<const TImpl *>(this);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								src/ArduinoJson/Polyfills/attributes.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								src/ArduinoJson/Polyfills/attributes.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER  // Visual Studio
 | 
			
		||||
 | 
			
		||||
#define FORCE_INLINE __forceinline
 | 
			
		||||
#define NO_INLINE __declspec(noinline)
 | 
			
		||||
#define DEPRECATED(msg) __declspec(deprecated(msg))
 | 
			
		||||
 | 
			
		||||
#elif defined(__GNUC__)  // GCC or Clang
 | 
			
		||||
 | 
			
		||||
#define FORCE_INLINE __attribute__((always_inline))
 | 
			
		||||
#define NO_INLINE __attribute__((noinline))
 | 
			
		||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
 | 
			
		||||
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
 | 
			
		||||
#else
 | 
			
		||||
#define DEPRECATED(msg) __attribute__((deprecated))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else  // Other compilers
 | 
			
		||||
 | 
			
		||||
#define FORCE_INLINE
 | 
			
		||||
#define NO_INLINE
 | 
			
		||||
#define DEPRECATED(msg)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										18
									
								
								src/ArduinoJson/Polyfills/ctype.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								src/ArduinoJson/Polyfills/ctype.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
 | 
			
		||||
inline bool isdigit(char c) {
 | 
			
		||||
  return '0' <= c && c <= '9';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool issign(char c) {
 | 
			
		||||
  return '-' == c || c == '+';
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								src/ArduinoJson/Polyfills/isFloat.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										38
									
								
								src/ArduinoJson/Polyfills/isFloat.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string.h>  // for strcmp
 | 
			
		||||
#include "./ctype.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
 | 
			
		||||
inline bool isFloat(const char* s) {
 | 
			
		||||
  if (!s) return false;
 | 
			
		||||
 | 
			
		||||
  if (!strcmp(s, "NaN")) return true;
 | 
			
		||||
  if (issign(*s)) s++;
 | 
			
		||||
  if (!strcmp(s, "Infinity")) return true;
 | 
			
		||||
  if (*s == '\0') return false;
 | 
			
		||||
 | 
			
		||||
  while (isdigit(*s)) s++;
 | 
			
		||||
 | 
			
		||||
  if (*s == '.') {
 | 
			
		||||
    s++;
 | 
			
		||||
    while (isdigit(*s)) s++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (*s == 'e' || *s == 'E') {
 | 
			
		||||
    s++;
 | 
			
		||||
    if (issign(*s)) s++;
 | 
			
		||||
    if (!isdigit(*s)) return false;
 | 
			
		||||
    while (isdigit(*s)) s++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return *s == '\0';
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/ArduinoJson/Polyfills/isInteger.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								src/ArduinoJson/Polyfills/isInteger.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "./ctype.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
 | 
			
		||||
inline bool isInteger(const char* s) {
 | 
			
		||||
  if (!s) return false;
 | 
			
		||||
  if (issign(*s)) s++;
 | 
			
		||||
  while (isdigit(*s)) s++;
 | 
			
		||||
  return *s == '\0';
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/ArduinoJson/Polyfills/math.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								src/ArduinoJson/Polyfills/math.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
template <typename T>
 | 
			
		||||
bool isNaN(T x) {
 | 
			
		||||
  return x != x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
bool isInfinity(T x) {
 | 
			
		||||
  return x != 0.0 && x * 2 == x;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/ArduinoJson/Polyfills/parseFloat.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										90
									
								
								src/ArduinoJson/Polyfills/parseFloat.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../TypeTraits/FloatTraits.hpp"
 | 
			
		||||
#include "./ctype.hpp"
 | 
			
		||||
#include "./math.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline T parseFloat(const char* s) {
 | 
			
		||||
  typedef TypeTraits::FloatTraits<T> traits;
 | 
			
		||||
  typedef typename traits::mantissa_type mantissa_t;
 | 
			
		||||
  typedef typename traits::exponent_type exponent_t;
 | 
			
		||||
 | 
			
		||||
  if (!s) return 0;  // NULL
 | 
			
		||||
 | 
			
		||||
  bool negative_result = false;
 | 
			
		||||
  switch (*s) {
 | 
			
		||||
    case '-':
 | 
			
		||||
      negative_result = true;
 | 
			
		||||
      s++;
 | 
			
		||||
      break;
 | 
			
		||||
    case '+':
 | 
			
		||||
      s++;
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (*s == 't') return 1;  // true
 | 
			
		||||
  if (*s == 'n' || *s == 'N') return traits::nan();
 | 
			
		||||
  if (*s == 'i' || *s == 'I')
 | 
			
		||||
    return negative_result ? -traits::inf() : traits::inf();
 | 
			
		||||
 | 
			
		||||
  mantissa_t mantissa = 0;
 | 
			
		||||
  exponent_t exponent_offset = 0;
 | 
			
		||||
 | 
			
		||||
  while (isdigit(*s)) {
 | 
			
		||||
    if (mantissa < traits::mantissa_max / 10)
 | 
			
		||||
      mantissa = mantissa * 10 + (*s - '0');
 | 
			
		||||
    else
 | 
			
		||||
      exponent_offset++;
 | 
			
		||||
    s++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (*s == '.') {
 | 
			
		||||
    s++;
 | 
			
		||||
    while (isdigit(*s)) {
 | 
			
		||||
      if (mantissa < traits::mantissa_max / 10) {
 | 
			
		||||
        mantissa = mantissa * 10 + (*s - '0');
 | 
			
		||||
        exponent_offset--;
 | 
			
		||||
      }
 | 
			
		||||
      s++;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int exponent = 0;
 | 
			
		||||
  if (*s == 'e' || *s == 'E') {
 | 
			
		||||
    s++;
 | 
			
		||||
    bool negative_exponent = false;
 | 
			
		||||
    if (*s == '-') {
 | 
			
		||||
      negative_exponent = true;
 | 
			
		||||
      s++;
 | 
			
		||||
    } else if (*s == '+') {
 | 
			
		||||
      s++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (isdigit(*s)) {
 | 
			
		||||
      exponent = exponent * 10 + (*s - '0');
 | 
			
		||||
      if (exponent + exponent_offset > traits::exponent_max) {
 | 
			
		||||
        if (negative_exponent)
 | 
			
		||||
          return negative_result ? -0.0f : 0.0f;
 | 
			
		||||
        else
 | 
			
		||||
          return negative_result ? -traits::inf() : traits::inf();
 | 
			
		||||
      }
 | 
			
		||||
      s++;
 | 
			
		||||
    }
 | 
			
		||||
    if (negative_exponent) exponent = -exponent;
 | 
			
		||||
  }
 | 
			
		||||
  exponent += exponent_offset;
 | 
			
		||||
 | 
			
		||||
  T result = traits::make_float(static_cast<T>(mantissa), exponent);
 | 
			
		||||
 | 
			
		||||
  return negative_result ? -result : result;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								src/ArduinoJson/Polyfills/parseInteger.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								src/ArduinoJson/Polyfills/parseInteger.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "./ctype.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Polyfills {
 | 
			
		||||
template <typename T>
 | 
			
		||||
T parseInteger(const char *s) {
 | 
			
		||||
  if (!s) return 0;  // NULL
 | 
			
		||||
 | 
			
		||||
  if (*s == 't') return 1;  // "true"
 | 
			
		||||
 | 
			
		||||
  T result = 0;
 | 
			
		||||
  bool negative_result = false;
 | 
			
		||||
 | 
			
		||||
  switch (*s) {
 | 
			
		||||
    case '-':
 | 
			
		||||
      negative_result = true;
 | 
			
		||||
      s++;
 | 
			
		||||
      break;
 | 
			
		||||
    case '+':
 | 
			
		||||
      s++;
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  while (isdigit(*s)) {
 | 
			
		||||
    result = T(result * 10 + T(*s - '0'));
 | 
			
		||||
    s++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return negative_result ? T(~result + 1) : result;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/ArduinoJson/RawJson.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								src/ArduinoJson/RawJson.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
// A special type of data that can be used to insert pregenerated JSON portions.
 | 
			
		||||
class RawJson {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit RawJson(const char* str) : _str(str) {}
 | 
			
		||||
  operator const char*() const {
 | 
			
		||||
    return _str;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const char* _str;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/ArduinoJson/Serialization/DummyPrint.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								src/ArduinoJson/Serialization/DummyPrint.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A dummy Print implementation used in JsonPrintable::measureLength()
 | 
			
		||||
class DummyPrint {
 | 
			
		||||
 public:
 | 
			
		||||
  size_t print(char) {
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char* s) {
 | 
			
		||||
    return strlen(s);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/ArduinoJson/Serialization/DynamicStringBuilder.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										35
									
								
								src/ArduinoJson/Serialization/DynamicStringBuilder.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../StringTraits/StringTraits.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A Print implementation that allows to write in a String
 | 
			
		||||
template <typename TString>
 | 
			
		||||
class DynamicStringBuilder {
 | 
			
		||||
 public:
 | 
			
		||||
  DynamicStringBuilder(TString &str) : _str(str) {}
 | 
			
		||||
 | 
			
		||||
  size_t print(char c) {
 | 
			
		||||
    StringTraits<TString>::append(_str, c);
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char *s) {
 | 
			
		||||
    size_t initialLen = _str.length();
 | 
			
		||||
    StringTraits<TString>::append(_str, s);
 | 
			
		||||
    return _str.length() - initialLen;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  DynamicStringBuilder &operator=(const DynamicStringBuilder &);
 | 
			
		||||
 | 
			
		||||
  TString &_str;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										89
									
								
								src/ArduinoJson/Serialization/FloatParts.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										89
									
								
								src/ArduinoJson/Serialization/FloatParts.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "../Polyfills/math.hpp"
 | 
			
		||||
#include "../TypeTraits/FloatTraits.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TFloat>
 | 
			
		||||
struct FloatParts {
 | 
			
		||||
  uint32_t integral;
 | 
			
		||||
  uint32_t decimal;
 | 
			
		||||
  int16_t exponent;
 | 
			
		||||
  int8_t decimalPlaces;
 | 
			
		||||
 | 
			
		||||
  FloatParts(TFloat value) {
 | 
			
		||||
    uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
 | 
			
		||||
    decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
 | 
			
		||||
 | 
			
		||||
    exponent = normalize(value);
 | 
			
		||||
 | 
			
		||||
    integral = uint32_t(value);
 | 
			
		||||
    // reduce number of decimal places by the number of integral places
 | 
			
		||||
    for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
 | 
			
		||||
      maxDecimalPart /= 10;
 | 
			
		||||
      decimalPlaces--;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
 | 
			
		||||
 | 
			
		||||
    decimal = uint32_t(remainder);
 | 
			
		||||
    remainder = remainder - TFloat(decimal);
 | 
			
		||||
 | 
			
		||||
    // rounding:
 | 
			
		||||
    // increment by 1 if remainder >= 0.5
 | 
			
		||||
    decimal += uint32_t(remainder * 2);
 | 
			
		||||
    if (decimal >= maxDecimalPart) {
 | 
			
		||||
      decimal = 0;
 | 
			
		||||
      integral++;
 | 
			
		||||
      if (exponent && integral >= 10) {
 | 
			
		||||
        exponent++;
 | 
			
		||||
        integral = 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // remove trailing zeros
 | 
			
		||||
    while (decimal % 10 == 0 && decimalPlaces > 0) {
 | 
			
		||||
      decimal /= 10;
 | 
			
		||||
      decimalPlaces--;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static int16_t normalize(TFloat& value) {
 | 
			
		||||
    typedef TypeTraits::FloatTraits<TFloat> traits;
 | 
			
		||||
    int16_t powersOf10 = 0;
 | 
			
		||||
 | 
			
		||||
    int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
 | 
			
		||||
    int bit = 1 << index;
 | 
			
		||||
 | 
			
		||||
    if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
 | 
			
		||||
      for (; index >= 0; index--) {
 | 
			
		||||
        if (value >= traits::positiveBinaryPowerOfTen(index)) {
 | 
			
		||||
          value *= traits::negativeBinaryPowerOfTen(index);
 | 
			
		||||
          powersOf10 = int16_t(powersOf10 + bit);
 | 
			
		||||
        }
 | 
			
		||||
        bit >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
 | 
			
		||||
      for (; index >= 0; index--) {
 | 
			
		||||
        if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
 | 
			
		||||
          value *= traits::positiveBinaryPowerOfTen(index);
 | 
			
		||||
          powersOf10 = int16_t(powersOf10 - bit);
 | 
			
		||||
        }
 | 
			
		||||
        bit >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return powersOf10;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								src/ArduinoJson/Serialization/IndentedPrint.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								src/ArduinoJson/Serialization/IndentedPrint.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Decorator on top of Print to allow indented output.
 | 
			
		||||
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
 | 
			
		||||
// for your own purpose, like logging.
 | 
			
		||||
template <typename Print>
 | 
			
		||||
class IndentedPrint {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit IndentedPrint(Print &p) : sink(&p) {
 | 
			
		||||
    level = 0;
 | 
			
		||||
    tabSize = 2;
 | 
			
		||||
    isNewLine = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(char c) {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    if (isNewLine) n += writeTabs();
 | 
			
		||||
    n += sink->print(c);
 | 
			
		||||
    isNewLine = c == '\n';
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char *s) {
 | 
			
		||||
    // TODO: optimize
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    while (*s) n += print(*s++);
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Adds one level of indentation
 | 
			
		||||
  void indent() {
 | 
			
		||||
    if (level < MAX_LEVEL) level++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Removes one level of indentation
 | 
			
		||||
  void unindent() {
 | 
			
		||||
    if (level > 0) level--;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the number of space printed for each level of indentation
 | 
			
		||||
  void setTabSize(uint8_t n) {
 | 
			
		||||
    if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  Print *sink;
 | 
			
		||||
  uint8_t level : 4;
 | 
			
		||||
  uint8_t tabSize : 3;
 | 
			
		||||
  bool isNewLine : 1;
 | 
			
		||||
 | 
			
		||||
  size_t writeTabs() {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static const int MAX_LEVEL = 15;    // because it's only 4 bits
 | 
			
		||||
  static const int MAX_TAB_SIZE = 7;  // because it's only 3 bits
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								src/ArduinoJson/Serialization/JsonPrintable.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										119
									
								
								src/ArduinoJson/Serialization/JsonPrintable.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "../TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "DummyPrint.hpp"
 | 
			
		||||
#include "DynamicStringBuilder.hpp"
 | 
			
		||||
#include "IndentedPrint.hpp"
 | 
			
		||||
#include "JsonSerializer.hpp"
 | 
			
		||||
#include "JsonWriter.hpp"
 | 
			
		||||
#include "Prettyfier.hpp"
 | 
			
		||||
#include "StaticStringBuilder.hpp"
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
#include "StreamPrintAdapter.hpp"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Implements all the overloads of printTo() and prettyPrintTo()
 | 
			
		||||
// Caution: this class use a template parameter to avoid virtual methods.
 | 
			
		||||
// This is a bit curious but allows to reduce the size of JsonVariant, JsonArray
 | 
			
		||||
// and JsonObject.
 | 
			
		||||
template <typename T>
 | 
			
		||||
class JsonPrintable {
 | 
			
		||||
 public:
 | 
			
		||||
  template <typename Print>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
 | 
			
		||||
                                size_t>::type
 | 
			
		||||
  printTo(Print &print) const {
 | 
			
		||||
    JsonWriter<Print> writer(print);
 | 
			
		||||
    JsonSerializer<JsonWriter<Print> >::serialize(downcast(), writer);
 | 
			
		||||
    return writer.bytesWritten();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
  std::ostream &printTo(std::ostream &os) const {
 | 
			
		||||
    StreamPrintAdapter adapter(os);
 | 
			
		||||
    printTo(adapter);
 | 
			
		||||
    return os;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  size_t printTo(char *buffer, size_t bufferSize) const {
 | 
			
		||||
    StaticStringBuilder sb(buffer, bufferSize);
 | 
			
		||||
    return printTo(sb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <size_t N>
 | 
			
		||||
  size_t printTo(char (&buffer)[N]) const {
 | 
			
		||||
    return printTo(buffer, N);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<StringTraits<TString>::has_append, size_t>::type
 | 
			
		||||
  printTo(TString &str) const {
 | 
			
		||||
    DynamicStringBuilder<TString> sb(str);
 | 
			
		||||
    return printTo(sb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename Print>
 | 
			
		||||
  size_t prettyPrintTo(IndentedPrint<Print> &print) const {
 | 
			
		||||
    Prettyfier<Print> p(print);
 | 
			
		||||
    return printTo(p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t prettyPrintTo(char *buffer, size_t bufferSize) const {
 | 
			
		||||
    StaticStringBuilder sb(buffer, bufferSize);
 | 
			
		||||
    return prettyPrintTo(sb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <size_t N>
 | 
			
		||||
  size_t prettyPrintTo(char (&buffer)[N]) const {
 | 
			
		||||
    return prettyPrintTo(buffer, N);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename Print>
 | 
			
		||||
  typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
 | 
			
		||||
                                size_t>::type
 | 
			
		||||
  prettyPrintTo(Print &print) const {
 | 
			
		||||
    IndentedPrint<Print> indentedPrint(print);
 | 
			
		||||
    return prettyPrintTo(indentedPrint);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TString>
 | 
			
		||||
  typename TypeTraits::EnableIf<StringTraits<TString>::has_append, size_t>::type
 | 
			
		||||
  prettyPrintTo(TString &str) const {
 | 
			
		||||
    DynamicStringBuilder<TString> sb(str);
 | 
			
		||||
    return prettyPrintTo(sb);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t measureLength() const {
 | 
			
		||||
    DummyPrint dp;
 | 
			
		||||
    return printTo(dp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t measurePrettyLength() const {
 | 
			
		||||
    DummyPrint dp;
 | 
			
		||||
    return prettyPrintTo(dp);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  const T &downcast() const {
 | 
			
		||||
    return *static_cast<const T *>(this);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
 | 
			
		||||
  return v.printTo(os);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								src/ArduinoJson/Serialization/JsonSerializer.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								src/ArduinoJson/Serialization/JsonSerializer.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonWriter.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
class JsonArray;
 | 
			
		||||
class JsonArraySubscript;
 | 
			
		||||
class JsonObject;
 | 
			
		||||
template <typename TKey>
 | 
			
		||||
class JsonObjectSubscript;
 | 
			
		||||
class JsonVariant;
 | 
			
		||||
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
class JsonSerializer {
 | 
			
		||||
 public:
 | 
			
		||||
  static void serialize(const JsonArray &, Writer &);
 | 
			
		||||
  static void serialize(const JsonArraySubscript &, Writer &);
 | 
			
		||||
  static void serialize(const JsonObject &, Writer &);
 | 
			
		||||
  template <typename TKey>
 | 
			
		||||
  static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
 | 
			
		||||
  static void serialize(const JsonVariant &, Writer &);
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								src/ArduinoJson/Serialization/JsonSerializerImpl.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										103
									
								
								src/ArduinoJson/Serialization/JsonSerializerImpl.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../JsonArray.hpp"
 | 
			
		||||
#include "../JsonArraySubscript.hpp"
 | 
			
		||||
#include "../JsonObject.hpp"
 | 
			
		||||
#include "../JsonObjectSubscript.hpp"
 | 
			
		||||
#include "../JsonVariant.hpp"
 | 
			
		||||
#include "JsonSerializer.hpp"
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 | 
			
		||||
    const JsonArray& array, Writer& writer) {
 | 
			
		||||
  writer.beginArray();
 | 
			
		||||
 | 
			
		||||
  JsonArray::const_iterator it = array.begin();
 | 
			
		||||
  while (it != array.end()) {
 | 
			
		||||
    serialize(*it, writer);
 | 
			
		||||
 | 
			
		||||
    ++it;
 | 
			
		||||
    if (it == array.end()) break;
 | 
			
		||||
 | 
			
		||||
    writer.writeComma();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  writer.endArray();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 | 
			
		||||
    const JsonArraySubscript& arraySubscript, Writer& writer) {
 | 
			
		||||
  serialize(arraySubscript.as<JsonVariant>(), writer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 | 
			
		||||
    const JsonObject& object, Writer& writer) {
 | 
			
		||||
  writer.beginObject();
 | 
			
		||||
 | 
			
		||||
  JsonObject::const_iterator it = object.begin();
 | 
			
		||||
  while (it != object.end()) {
 | 
			
		||||
    writer.writeString(it->key);
 | 
			
		||||
    writer.writeColon();
 | 
			
		||||
    serialize(it->value, writer);
 | 
			
		||||
 | 
			
		||||
    ++it;
 | 
			
		||||
    if (it == object.end()) break;
 | 
			
		||||
 | 
			
		||||
    writer.writeComma();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  writer.endObject();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
template <typename TKey>
 | 
			
		||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 | 
			
		||||
    const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) {
 | 
			
		||||
  serialize(objectSubscript.template as<JsonVariant>(), writer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Writer>
 | 
			
		||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
 | 
			
		||||
    const JsonVariant& variant, Writer& writer) {
 | 
			
		||||
  switch (variant._type) {
 | 
			
		||||
    case JSON_FLOAT:
 | 
			
		||||
      writer.writeFloat(variant._content.asFloat);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_ARRAY:
 | 
			
		||||
      serialize(*variant._content.asArray, writer);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_OBJECT:
 | 
			
		||||
      serialize(*variant._content.asObject, writer);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_STRING:
 | 
			
		||||
      writer.writeString(variant._content.asString);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_UNPARSED:
 | 
			
		||||
      writer.writeRaw(variant._content.asString);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_NEGATIVE_INTEGER:
 | 
			
		||||
      writer.writeRaw('-');  // Falls through.
 | 
			
		||||
 | 
			
		||||
    case JSON_POSITIVE_INTEGER:
 | 
			
		||||
      writer.writeInteger(variant._content.asInteger);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    case JSON_BOOLEAN:
 | 
			
		||||
      writer.writeBoolean(variant._content.asInteger != 0);
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    default:  // JSON_UNDEFINED
 | 
			
		||||
      return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										155
									
								
								src/ArduinoJson/Serialization/JsonWriter.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										155
									
								
								src/ArduinoJson/Serialization/JsonWriter.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "../Data/Encoding.hpp"
 | 
			
		||||
#include "../Data/JsonInteger.hpp"
 | 
			
		||||
#include "../Polyfills/attributes.hpp"
 | 
			
		||||
#include "../Serialization/FloatParts.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Writes the JSON tokens to a Print implementation
 | 
			
		||||
// This class is used by:
 | 
			
		||||
// - JsonArray::writeTo()
 | 
			
		||||
// - JsonObject::writeTo()
 | 
			
		||||
// - JsonVariant::writeTo()
 | 
			
		||||
// Its derived by PrettyJsonWriter that overrides some members to add
 | 
			
		||||
// indentation.
 | 
			
		||||
template <typename Print>
 | 
			
		||||
class JsonWriter {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
 | 
			
		||||
 | 
			
		||||
  // Returns the number of bytes sent to the Print implementation.
 | 
			
		||||
  // This is very handy for implementations of printTo() that must return the
 | 
			
		||||
  // number of bytes written.
 | 
			
		||||
  size_t bytesWritten() const {
 | 
			
		||||
    return _length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void beginArray() {
 | 
			
		||||
    writeRaw('[');
 | 
			
		||||
  }
 | 
			
		||||
  void endArray() {
 | 
			
		||||
    writeRaw(']');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void beginObject() {
 | 
			
		||||
    writeRaw('{');
 | 
			
		||||
  }
 | 
			
		||||
  void endObject() {
 | 
			
		||||
    writeRaw('}');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeColon() {
 | 
			
		||||
    writeRaw(':');
 | 
			
		||||
  }
 | 
			
		||||
  void writeComma() {
 | 
			
		||||
    writeRaw(',');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeBoolean(bool value) {
 | 
			
		||||
    writeRaw(value ? "true" : "false");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeString(const char *value) {
 | 
			
		||||
    if (!value) {
 | 
			
		||||
      writeRaw("null");
 | 
			
		||||
    } else {
 | 
			
		||||
      writeRaw('\"');
 | 
			
		||||
      while (*value) writeChar(*value++);
 | 
			
		||||
      writeRaw('\"');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeChar(char c) {
 | 
			
		||||
    char specialChar = Encoding::escapeChar(c);
 | 
			
		||||
    if (specialChar) {
 | 
			
		||||
      writeRaw('\\');
 | 
			
		||||
      writeRaw(specialChar);
 | 
			
		||||
    } else {
 | 
			
		||||
      writeRaw(c);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename TFloat>
 | 
			
		||||
  void writeFloat(TFloat value) {
 | 
			
		||||
    if (Polyfills::isNaN(value)) return writeRaw("NaN");
 | 
			
		||||
 | 
			
		||||
    if (value < 0.0) {
 | 
			
		||||
      writeRaw('-');
 | 
			
		||||
      value = -value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
 | 
			
		||||
 | 
			
		||||
    FloatParts<TFloat> parts(value);
 | 
			
		||||
 | 
			
		||||
    writeInteger(parts.integral);
 | 
			
		||||
    if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces);
 | 
			
		||||
 | 
			
		||||
    if (parts.exponent < 0) {
 | 
			
		||||
      writeRaw("e-");
 | 
			
		||||
      writeInteger(-parts.exponent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (parts.exponent > 0) {
 | 
			
		||||
      writeRaw('e');
 | 
			
		||||
      writeInteger(parts.exponent);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename UInt>
 | 
			
		||||
  void writeInteger(UInt value) {
 | 
			
		||||
    char buffer[22];
 | 
			
		||||
    char *end = buffer + sizeof(buffer) - 1;
 | 
			
		||||
    char *ptr = end;
 | 
			
		||||
 | 
			
		||||
    *ptr = 0;
 | 
			
		||||
    do {
 | 
			
		||||
      *--ptr = char(value % 10 + '0');
 | 
			
		||||
      value = UInt(value / 10);
 | 
			
		||||
    } while (value);
 | 
			
		||||
 | 
			
		||||
    writeRaw(ptr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeDecimals(uint32_t value, int8_t width) {
 | 
			
		||||
    // buffer should be big enough for all digits, the dot and the null
 | 
			
		||||
    // terminator
 | 
			
		||||
    char buffer[16];
 | 
			
		||||
    char *ptr = buffer + sizeof(buffer) - 1;
 | 
			
		||||
 | 
			
		||||
    // write the string in reverse order
 | 
			
		||||
    *ptr = 0;
 | 
			
		||||
    while (width--) {
 | 
			
		||||
      *--ptr = char(value % 10 + '0');
 | 
			
		||||
      value /= 10;
 | 
			
		||||
    }
 | 
			
		||||
    *--ptr = '.';
 | 
			
		||||
 | 
			
		||||
    // and dump it in the right order
 | 
			
		||||
    writeRaw(ptr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void writeRaw(const char *s) {
 | 
			
		||||
    _length += _sink.print(s);
 | 
			
		||||
  }
 | 
			
		||||
  void writeRaw(char c) {
 | 
			
		||||
    _length += _sink.print(c);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  Print &_sink;
 | 
			
		||||
  size_t _length;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  JsonWriter &operator=(const JsonWriter &);  // cannot be assigned
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										133
									
								
								src/ArduinoJson/Serialization/Prettyfier.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										133
									
								
								src/ArduinoJson/Serialization/Prettyfier.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "IndentedPrint.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// Converts a compact JSON string into an indented one.
 | 
			
		||||
template <typename Print>
 | 
			
		||||
class Prettyfier {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) {
 | 
			
		||||
    _previousChar = 0;
 | 
			
		||||
    _inString = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(char c) {
 | 
			
		||||
    size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
 | 
			
		||||
    _previousChar = c;
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char* s) {
 | 
			
		||||
    // TODO: optimize
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    while (*s) n += print(*s++);
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  Prettyfier& operator=(const Prettyfier&);  // cannot be assigned
 | 
			
		||||
 | 
			
		||||
  bool inEmptyBlock() {
 | 
			
		||||
    return _previousChar == '{' || _previousChar == '[';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t handleStringChar(char c) {
 | 
			
		||||
    bool isQuote = c == '"' && _previousChar != '\\';
 | 
			
		||||
 | 
			
		||||
    if (isQuote) _inString = false;
 | 
			
		||||
 | 
			
		||||
    return _sink.print(c);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t handleMarkupChar(char c) {
 | 
			
		||||
    switch (c) {
 | 
			
		||||
      case '{':
 | 
			
		||||
      case '[':
 | 
			
		||||
        return writeBlockOpen(c);
 | 
			
		||||
 | 
			
		||||
      case '}':
 | 
			
		||||
      case ']':
 | 
			
		||||
        return writeBlockClose(c);
 | 
			
		||||
 | 
			
		||||
      case ':':
 | 
			
		||||
        return writeColon();
 | 
			
		||||
 | 
			
		||||
      case ',':
 | 
			
		||||
        return writeComma();
 | 
			
		||||
 | 
			
		||||
      case '"':
 | 
			
		||||
        return writeQuoteOpen();
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
        return writeNormalChar(c);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeBlockClose(char c) {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += unindentIfNeeded();
 | 
			
		||||
    n += _sink.print(c);
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeBlockOpen(char c) {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += indentIfNeeded();
 | 
			
		||||
    n += _sink.print(c);
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeColon() {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += _sink.print(": ");
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeComma() {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += _sink.print(",\r\n");
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeQuoteOpen() {
 | 
			
		||||
    _inString = true;
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += indentIfNeeded();
 | 
			
		||||
    n += _sink.print('"');
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t writeNormalChar(char c) {
 | 
			
		||||
    size_t n = 0;
 | 
			
		||||
    n += indentIfNeeded();
 | 
			
		||||
    n += _sink.print(c);
 | 
			
		||||
    return n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t indentIfNeeded() {
 | 
			
		||||
    if (!inEmptyBlock()) return 0;
 | 
			
		||||
 | 
			
		||||
    _sink.indent();
 | 
			
		||||
    return _sink.print("\r\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t unindentIfNeeded() {
 | 
			
		||||
    if (inEmptyBlock()) return 0;
 | 
			
		||||
 | 
			
		||||
    _sink.unindent();
 | 
			
		||||
    return _sink.print("\r\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char _previousChar;
 | 
			
		||||
  IndentedPrint<Print>& _sink;
 | 
			
		||||
  bool _inString;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								src/ArduinoJson/Serialization/StaticStringBuilder.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								src/ArduinoJson/Serialization/StaticStringBuilder.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
// A Print implementation that allows to write in a char[]
 | 
			
		||||
class StaticStringBuilder {
 | 
			
		||||
 public:
 | 
			
		||||
  StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) {
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(char c) {
 | 
			
		||||
    if (p >= end) return 0;
 | 
			
		||||
    *p++ = c;
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char *s) {
 | 
			
		||||
    char *begin = p;
 | 
			
		||||
    while (p < end && *s) *p++ = *s++;
 | 
			
		||||
    *p = '\0';
 | 
			
		||||
    return size_t(p - begin);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  char *end;
 | 
			
		||||
  char *p;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										39
									
								
								src/ArduinoJson/Serialization/StreamPrintAdapter.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								src/ArduinoJson/Serialization/StreamPrintAdapter.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
 | 
			
		||||
#include <ostream>
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
class StreamPrintAdapter {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
 | 
			
		||||
 | 
			
		||||
  size_t print(char c) {
 | 
			
		||||
    _os << c;
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  size_t print(const char* s) {
 | 
			
		||||
    _os << s;
 | 
			
		||||
    return strlen(s);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // cannot be assigned
 | 
			
		||||
  StreamPrintAdapter& operator=(const StreamPrintAdapter&);
 | 
			
		||||
 | 
			
		||||
  std::ostream& _os;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif  // ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
							
								
								
									
										123
									
								
								src/ArduinoJson/StaticJsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								src/ArduinoJson/StaticJsonBuffer.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "JsonBufferBase.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
 | 
			
		||||
class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
 | 
			
		||||
 public:
 | 
			
		||||
  class String {
 | 
			
		||||
   public:
 | 
			
		||||
    String(StaticJsonBufferBase* parent) : _parent(parent) {
 | 
			
		||||
      _start = parent->_buffer + parent->_size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void append(char c) {
 | 
			
		||||
      if (_parent->canAlloc(1)) {
 | 
			
		||||
        char* last = static_cast<char*>(_parent->doAlloc(1));
 | 
			
		||||
        *last = c;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char* c_str() const {
 | 
			
		||||
      if (_parent->canAlloc(1)) {
 | 
			
		||||
        char* last = static_cast<char*>(_parent->doAlloc(1));
 | 
			
		||||
        *last = '\0';
 | 
			
		||||
        return _start;
 | 
			
		||||
      } else {
 | 
			
		||||
        return NULL;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    StaticJsonBufferBase* _parent;
 | 
			
		||||
    char* _start;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  StaticJsonBufferBase(char* buffer, size_t capa)
 | 
			
		||||
      : _buffer(buffer), _capacity(capa), _size(0) {}
 | 
			
		||||
 | 
			
		||||
  // Gets the capacity of the buffer in bytes
 | 
			
		||||
  size_t capacity() const {
 | 
			
		||||
    return _capacity;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Gets the current usage of the buffer in bytes
 | 
			
		||||
  size_t size() const {
 | 
			
		||||
    return _size;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocates the specified amount of bytes in the buffer
 | 
			
		||||
  virtual void* alloc(size_t bytes) {
 | 
			
		||||
    alignNextAlloc();
 | 
			
		||||
    if (!canAlloc(bytes)) return NULL;
 | 
			
		||||
    return doAlloc(bytes);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Resets the buffer.
 | 
			
		||||
  // USE WITH CAUTION: this invalidates all previously allocated data
 | 
			
		||||
  void clear() {
 | 
			
		||||
    _size = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  String startString() {
 | 
			
		||||
    return String(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  ~StaticJsonBufferBase() {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  void alignNextAlloc() {
 | 
			
		||||
    _size = round_size_up(_size);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool canAlloc(size_t bytes) const {
 | 
			
		||||
    return _size + bytes <= _capacity;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void* doAlloc(size_t bytes) {
 | 
			
		||||
    void* p = &_buffer[_size];
 | 
			
		||||
    _size += bytes;
 | 
			
		||||
    return p;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char* _buffer;
 | 
			
		||||
  size_t _capacity;
 | 
			
		||||
  size_t _size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic push
 | 
			
		||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#endif
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Implements a JsonBuffer with fixed memory allocation.
 | 
			
		||||
// The template paramenter CAPACITY specifies the capacity of the buffer in
 | 
			
		||||
// bytes.
 | 
			
		||||
template <size_t CAPACITY>
 | 
			
		||||
class StaticJsonBuffer : public StaticJsonBufferBase {
 | 
			
		||||
 public:
 | 
			
		||||
  explicit StaticJsonBuffer() : StaticJsonBufferBase(_buffer, CAPACITY) {}
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  char _buffer[CAPACITY];
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#pragma clang diagnostic pop
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										58
									
								
								src/ArduinoJson/StringTraits/ArduinoStream.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										58
									
								
								src/ArduinoJson/StringTraits/ArduinoStream.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
 | 
			
		||||
 | 
			
		||||
#include <Stream.h>
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
struct ArduinoStreamTraits {
 | 
			
		||||
  class Reader {
 | 
			
		||||
    Stream& _stream;
 | 
			
		||||
    char _current, _next;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
    Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {}
 | 
			
		||||
 | 
			
		||||
    void move() {
 | 
			
		||||
      _current = _next;
 | 
			
		||||
      _next = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char current() {
 | 
			
		||||
      if (!_current) _current = read();
 | 
			
		||||
      return _current;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char next() {
 | 
			
		||||
      // assumes that current() has been called
 | 
			
		||||
      if (!_next) _next = read();
 | 
			
		||||
      return _next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    char read() {
 | 
			
		||||
      // don't use _stream.read() as it ignores the timeout
 | 
			
		||||
      char c = 0;
 | 
			
		||||
      _stream.readBytes(&c, 1);
 | 
			
		||||
      return c;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TStream>
 | 
			
		||||
struct StringTraits<TStream,
 | 
			
		||||
                    // match any type that is derived from Stream:
 | 
			
		||||
                    typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
 | 
			
		||||
                        Stream, typename TypeTraits::RemoveReference<
 | 
			
		||||
                                    TStream>::type>::value>::type>
 | 
			
		||||
    : ArduinoStreamTraits {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										55
									
								
								src/ArduinoJson/StringTraits/CharPointer.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										55
									
								
								src/ArduinoJson/StringTraits/CharPointer.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TChar>
 | 
			
		||||
struct CharPointerTraits {
 | 
			
		||||
  class Reader {
 | 
			
		||||
    const TChar* _ptr;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
    Reader(const TChar* ptr)
 | 
			
		||||
        : _ptr(ptr ? ptr : reinterpret_cast<const TChar*>("")) {}
 | 
			
		||||
 | 
			
		||||
    void move() {
 | 
			
		||||
      ++_ptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char current() const {
 | 
			
		||||
      return char(_ptr[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char next() const {
 | 
			
		||||
      return char(_ptr[1]);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static bool equals(const TChar* str, const char* expected) {
 | 
			
		||||
    return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename Buffer>
 | 
			
		||||
  static char* duplicate(const TChar* str, Buffer* buffer) {
 | 
			
		||||
    if (!str) return NULL;
 | 
			
		||||
    size_t size = strlen(reinterpret_cast<const char*>(str)) + 1;
 | 
			
		||||
    void* dup = buffer->alloc(size);
 | 
			
		||||
    if (dup != NULL) memcpy(dup, str, size);
 | 
			
		||||
    return static_cast<char*>(dup);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static const bool has_append = false;
 | 
			
		||||
  static const bool has_equals = true;
 | 
			
		||||
  static const bool should_duplicate = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TChar>
 | 
			
		||||
struct StringTraits<TChar*, typename TypeTraits::EnableIf<
 | 
			
		||||
                                TypeTraits::IsChar<TChar>::value>::type>
 | 
			
		||||
    : CharPointerTraits<TChar> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								src/ArduinoJson/StringTraits/FlashString.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										53
									
								
								src/ArduinoJson/StringTraits/FlashString.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_PROGMEM
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
template <>
 | 
			
		||||
struct StringTraits<const __FlashStringHelper*, void> {
 | 
			
		||||
  class Reader {
 | 
			
		||||
    const char* _ptr;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
    Reader(const __FlashStringHelper* ptr)
 | 
			
		||||
        : _ptr(reinterpret_cast<const char*>(ptr)) {}
 | 
			
		||||
 | 
			
		||||
    void move() {
 | 
			
		||||
      _ptr++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char current() const {
 | 
			
		||||
      return pgm_read_byte_near(_ptr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char next() const {
 | 
			
		||||
      return pgm_read_byte_near(_ptr + 1);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static bool equals(const __FlashStringHelper* str, const char* expected) {
 | 
			
		||||
    return strcmp_P(expected, (const char*)str) == 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename Buffer>
 | 
			
		||||
  static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
 | 
			
		||||
    if (!str) return NULL;
 | 
			
		||||
    size_t size = strlen_P((const char*)str) + 1;
 | 
			
		||||
    void* dup = buffer->alloc(size);
 | 
			
		||||
    if (dup != NULL) memcpy_P(dup, (const char*)str, size);
 | 
			
		||||
    return static_cast<char*>(dup);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static const bool has_append = false;
 | 
			
		||||
  static const bool has_equals = true;
 | 
			
		||||
  static const bool should_duplicate = true;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										57
									
								
								src/ArduinoJson/StringTraits/StdStream.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										57
									
								
								src/ArduinoJson/StringTraits/StdStream.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STREAM
 | 
			
		||||
 | 
			
		||||
#include <istream>
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
struct StdStreamTraits {
 | 
			
		||||
  class Reader {
 | 
			
		||||
    std::istream& _stream;
 | 
			
		||||
    char _current, _next;
 | 
			
		||||
 | 
			
		||||
   public:
 | 
			
		||||
    Reader(std::istream& stream) : _stream(stream), _current(0), _next(0) {}
 | 
			
		||||
 | 
			
		||||
    void move() {
 | 
			
		||||
      _current = _next;
 | 
			
		||||
      _next = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char current() {
 | 
			
		||||
      if (!_current) _current = read();
 | 
			
		||||
      return _current;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char next() {
 | 
			
		||||
      // assumes that current() has been called
 | 
			
		||||
      if (!_next) _next = read();
 | 
			
		||||
      return _next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
   private:
 | 
			
		||||
    Reader& operator=(const Reader&);  // Visual Studio C4512
 | 
			
		||||
 | 
			
		||||
    char read() {
 | 
			
		||||
      return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename TStream>
 | 
			
		||||
struct StringTraits<TStream,
 | 
			
		||||
                    // match any type that is derived from std::istream:
 | 
			
		||||
                    typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
 | 
			
		||||
                        std::istream, typename TypeTraits::RemoveReference<
 | 
			
		||||
                                          TStream>::type>::value>::type>
 | 
			
		||||
    : StdStreamTraits {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										67
									
								
								src/ArduinoJson/StringTraits/StdString.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								src/ArduinoJson/StringTraits/StdString.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STRING || ARDUINOJSON_ENABLE_ARDUINO_STRING
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
 | 
			
		||||
#include <WString.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STRING
 | 
			
		||||
#include <string>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TString>
 | 
			
		||||
struct StdStringTraits {
 | 
			
		||||
  template <typename Buffer>
 | 
			
		||||
  static char* duplicate(const TString& str, Buffer* buffer) {
 | 
			
		||||
    if (!str.c_str()) return NULL;  // <- Arduino string can return NULL
 | 
			
		||||
    size_t size = str.length() + 1;
 | 
			
		||||
    void* dup = buffer->alloc(size);
 | 
			
		||||
    if (dup != NULL) memcpy(dup, str.c_str(), size);
 | 
			
		||||
    return static_cast<char*>(dup);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct Reader : CharPointerTraits<char>::Reader {
 | 
			
		||||
    Reader(const TString& str) : CharPointerTraits<char>::Reader(str.c_str()) {}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static bool equals(const TString& str, const char* expected) {
 | 
			
		||||
    return 0 == strcmp(str.c_str(), expected);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static void append(TString& str, char c) {
 | 
			
		||||
    str += c;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static void append(TString& str, const char* s) {
 | 
			
		||||
    str += s;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static const bool has_append = true;
 | 
			
		||||
  static const bool has_equals = true;
 | 
			
		||||
  static const bool should_duplicate = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
 | 
			
		||||
template <>
 | 
			
		||||
struct StringTraits<String, void> : StdStringTraits<String> {};
 | 
			
		||||
template <>
 | 
			
		||||
struct StringTraits<StringSumHelper, void> : StdStringTraits<StringSumHelper> {
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_ENABLE_STD_STRING
 | 
			
		||||
template <>
 | 
			
		||||
struct StringTraits<std::string, void> : StdStringTraits<std::string> {};
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										47
									
								
								src/ArduinoJson/StringTraits/StringTraits.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										47
									
								
								src/ArduinoJson/StringTraits/StringTraits.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "../TypeTraits/EnableIf.hpp"
 | 
			
		||||
#include "../TypeTraits/IsBaseOf.hpp"
 | 
			
		||||
#include "../TypeTraits/IsChar.hpp"
 | 
			
		||||
#include "../TypeTraits/RemoveReference.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace Internals {
 | 
			
		||||
 | 
			
		||||
template <typename TString, typename Enable = void>
 | 
			
		||||
struct StringTraits {};
 | 
			
		||||
 | 
			
		||||
template <typename TString>
 | 
			
		||||
struct StringTraits<const TString, void> : StringTraits<TString> {};
 | 
			
		||||
 | 
			
		||||
template <typename TString>
 | 
			
		||||
struct StringTraits<TString&, void> : StringTraits<TString> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "ArduinoStream.hpp"
 | 
			
		||||
#include "CharPointer.hpp"
 | 
			
		||||
#include "FlashString.hpp"
 | 
			
		||||
#include "StdStream.hpp"
 | 
			
		||||
#include "StdString.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
template <typename T, typename Enable = void>
 | 
			
		||||
struct IsString {
 | 
			
		||||
  static const bool value = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsString<T, typename TypeTraits::EnableIf<
 | 
			
		||||
                       Internals::StringTraits<T>::has_equals>::type> {
 | 
			
		||||
  static const bool value = Internals::StringTraits<T>::has_equals;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/ArduinoJson/TypeTraits/EnableIf.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								src/ArduinoJson/TypeTraits/EnableIf.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that return the type T if Condition is true.
 | 
			
		||||
template <bool Condition, typename T = void>
 | 
			
		||||
struct EnableIf {};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct EnableIf<true, T> {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								src/ArduinoJson/TypeTraits/FloatTraits.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										150
									
								
								src/ArduinoJson/TypeTraits/FloatTraits.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>  // for size_t
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "../Polyfills/math.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
template <typename T, size_t = sizeof(T)>
 | 
			
		||||
struct FloatTraits {};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct FloatTraits<T, 8 /*64bits*/> {
 | 
			
		||||
  typedef int64_t mantissa_type;
 | 
			
		||||
  static const short mantissa_bits = 52;
 | 
			
		||||
  static const mantissa_type mantissa_max =
 | 
			
		||||
      (static_cast<mantissa_type>(1) << mantissa_bits) - 1;
 | 
			
		||||
 | 
			
		||||
  typedef int16_t exponent_type;
 | 
			
		||||
  static const exponent_type exponent_max = 308;
 | 
			
		||||
 | 
			
		||||
  template <typename TExponent>
 | 
			
		||||
  static T make_float(T m, TExponent e) {
 | 
			
		||||
    if (e > 0) {
 | 
			
		||||
      for (uint8_t index = 0; e != 0; index++) {
 | 
			
		||||
        if (e & 1) m *= positiveBinaryPowerOfTen(index);
 | 
			
		||||
        e >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      e = TExponent(-e);
 | 
			
		||||
      for (uint8_t index = 0; e != 0; index++) {
 | 
			
		||||
        if (e & 1) m *= negativeBinaryPowerOfTen(index);
 | 
			
		||||
        e >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return m;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T positiveBinaryPowerOfTen(int index) {
 | 
			
		||||
    static T factors[] = {
 | 
			
		||||
        1e1, 1e2, 1e4, 1e8, 1e16, 1e32,
 | 
			
		||||
        // workaround to support platforms with single precision literals
 | 
			
		||||
        forge(0x4D384F03, 0xE93FF9F5), forge(0x5A827748, 0xF9301D32),
 | 
			
		||||
        forge(0x75154FDD, 0x7F73BF3C)};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T negativeBinaryPowerOfTen(int index) {
 | 
			
		||||
    static T factors[] = {
 | 
			
		||||
        1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32,
 | 
			
		||||
        // workaround to support platforms with single precision literals
 | 
			
		||||
        forge(0x32A50FFD, 0x44F4A73D), forge(0x255BBA08, 0xCF8C979D),
 | 
			
		||||
        forge(0x0AC80628, 0x64AC6F43)};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T negativeBinaryPowerOfTenPlusOne(int index) {
 | 
			
		||||
    static T factors[] = {
 | 
			
		||||
        1e0, 1e-1, 1e-3, 1e-7, 1e-15, 1e-31,
 | 
			
		||||
        // workaround to support platforms with single precision literals
 | 
			
		||||
        forge(0x32DA53FC, 0x9631D10D), forge(0x25915445, 0x81B7DEC2),
 | 
			
		||||
        forge(0x0AFE07B2, 0x7DD78B14)};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T nan() {
 | 
			
		||||
    return forge(0x7ff80000, 0x00000000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T inf() {
 | 
			
		||||
    return forge(0x7ff00000, 0x00000000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T forge(uint32_t msb, uint32_t lsb) {
 | 
			
		||||
    union {
 | 
			
		||||
      uint64_t integerBits;
 | 
			
		||||
      T floatBits;
 | 
			
		||||
    };
 | 
			
		||||
    integerBits = (uint64_t(msb) << 32) | lsb;
 | 
			
		||||
    return floatBits;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct FloatTraits<T, 4 /*32bits*/> {
 | 
			
		||||
  typedef int32_t mantissa_type;
 | 
			
		||||
  static const short mantissa_bits = 23;
 | 
			
		||||
  static const mantissa_type mantissa_max =
 | 
			
		||||
      (static_cast<mantissa_type>(1) << mantissa_bits) - 1;
 | 
			
		||||
 | 
			
		||||
  typedef int8_t exponent_type;
 | 
			
		||||
  static const exponent_type exponent_max = 38;
 | 
			
		||||
 | 
			
		||||
  template <typename TExponent>
 | 
			
		||||
  static T make_float(T m, TExponent e) {
 | 
			
		||||
    if (e > 0) {
 | 
			
		||||
      for (uint8_t index = 0; e != 0; index++) {
 | 
			
		||||
        if (e & 1) m *= positiveBinaryPowerOfTen(index);
 | 
			
		||||
        e >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      e = -e;
 | 
			
		||||
      for (uint8_t index = 0; e != 0; index++) {
 | 
			
		||||
        if (e & 1) m *= negativeBinaryPowerOfTen(index);
 | 
			
		||||
        e >>= 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return m;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T positiveBinaryPowerOfTen(int index) {
 | 
			
		||||
    static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T negativeBinaryPowerOfTen(int index) {
 | 
			
		||||
    static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T negativeBinaryPowerOfTenPlusOne(int index) {
 | 
			
		||||
    static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
 | 
			
		||||
    return factors[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T forge(uint32_t bits) {
 | 
			
		||||
    union {
 | 
			
		||||
      uint32_t integerBits;
 | 
			
		||||
      T floatBits;
 | 
			
		||||
    };
 | 
			
		||||
    integerBits = bits;
 | 
			
		||||
    return floatBits;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T nan() {
 | 
			
		||||
    return forge(0x7fc00000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static T inf() {
 | 
			
		||||
    return forge(0x7f800000);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ArduinoJson/TypeTraits/IsArray.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										24
									
								
								src/ArduinoJson/TypeTraits/IsArray.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that return the type T without the const modifier
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsArray {
 | 
			
		||||
  static const bool value = false;
 | 
			
		||||
};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsArray<T[]> {
 | 
			
		||||
  static const bool value = true;
 | 
			
		||||
};
 | 
			
		||||
template <typename T, size_t N>
 | 
			
		||||
struct IsArray<T[N]> {
 | 
			
		||||
  static const bool value = true;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/ArduinoJson/TypeTraits/IsBaseOf.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								src/ArduinoJson/TypeTraits/IsBaseOf.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if Derived inherits from TBase is an
 | 
			
		||||
// integral type.
 | 
			
		||||
template <typename TBase, typename TDerived>
 | 
			
		||||
class IsBaseOf {
 | 
			
		||||
 protected:  // <- to avoid GCC's "all member functions in class are private"
 | 
			
		||||
  typedef char Yes[1];
 | 
			
		||||
  typedef char No[2];
 | 
			
		||||
 | 
			
		||||
  static Yes &probe(const TBase *);
 | 
			
		||||
  static No &probe(...);
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  enum {
 | 
			
		||||
    value = sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes)
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								src/ArduinoJson/TypeTraits/IsChar.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								src/ArduinoJson/TypeTraits/IsChar.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if T is a charater
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsChar {
 | 
			
		||||
  static const bool value = IsSame<T, char>::value ||
 | 
			
		||||
                            IsSame<T, signed char>::value ||
 | 
			
		||||
                            IsSame<T, unsigned char>::value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsChar<const T> : IsChar<T> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								src/ArduinoJson/TypeTraits/IsConst.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										21
									
								
								src/ArduinoJson/TypeTraits/IsConst.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that return the type T without the const modifier
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsConst {
 | 
			
		||||
  static const bool value = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsConst<const T> {
 | 
			
		||||
  static const bool value = true;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if T is a floating point type
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsFloatingPoint {
 | 
			
		||||
  static const bool value = IsSame<T, float>::value || IsSame<T, double>::value;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								src/ArduinoJson/TypeTraits/IsIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										26
									
								
								src/ArduinoJson/TypeTraits/IsIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "IsSame.hpp"
 | 
			
		||||
#include "IsSignedIntegral.hpp"
 | 
			
		||||
#include "IsUnsignedIntegral.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if T is an integral type.
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsIntegral {
 | 
			
		||||
  static const bool value = TypeTraits::IsSignedIntegral<T>::value ||
 | 
			
		||||
                            TypeTraits::IsUnsignedIntegral<T>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, char>::value;
 | 
			
		||||
  // CAUTION: differs from std::is_integral as it doesn't include bool
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsIntegral<const T> : IsIntegral<T> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								src/ArduinoJson/TypeTraits/IsSame.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										21
									
								
								src/ArduinoJson/TypeTraits/IsSame.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if types T and U are the same.
 | 
			
		||||
template <typename T, typename U>
 | 
			
		||||
struct IsSame {
 | 
			
		||||
  static const bool value = false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsSame<T, T> {
 | 
			
		||||
  static const bool value = true;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if T is an integral type.
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsSignedIntegral {
 | 
			
		||||
  static const bool value = TypeTraits::IsSame<T, signed char>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, signed short>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, signed int>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, signed long>::value ||
 | 
			
		||||
#if ARDUINOJSON_USE_LONG_LONG
 | 
			
		||||
                            TypeTraits::IsSame<T, signed long long>::value ||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_USE_INT64
 | 
			
		||||
                            TypeTraits::IsSame<T, signed __int64>::value ||
 | 
			
		||||
#endif
 | 
			
		||||
                            false;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "../Configuration.hpp"
 | 
			
		||||
#include "IsSame.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that returns true if T is an integral type.
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsUnsignedIntegral {
 | 
			
		||||
  static const bool value = TypeTraits::IsSame<T, unsigned char>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, unsigned short>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, unsigned int>::value ||
 | 
			
		||||
                            TypeTraits::IsSame<T, unsigned long>::value ||
 | 
			
		||||
#if ARDUINOJSON_USE_LONG_LONG
 | 
			
		||||
                            TypeTraits::IsSame<T, unsigned long long>::value ||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ARDUINOJSON_USE_INT64
 | 
			
		||||
                            TypeTraits::IsSame<T, unsigned __int64>::value ||
 | 
			
		||||
#endif
 | 
			
		||||
                            false;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/ArduinoJson/TypeTraits/IsVariant.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								src/ArduinoJson/TypeTraits/IsVariant.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "IsBaseOf.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
class JsonVariantTag {};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct IsVariant : IsBaseOf<JsonVariantTag, T> {};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/ArduinoJson/TypeTraits/RemoveConst.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								src/ArduinoJson/TypeTraits/RemoveConst.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that return the type T without the const modifier
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RemoveConst {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RemoveConst<const T> {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/ArduinoJson/TypeTraits/RemoveReference.hpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								src/ArduinoJson/TypeTraits/RemoveReference.hpp
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// ArduinoJson - arduinojson.org
 | 
			
		||||
// Copyright Benoit Blanchon 2014-2017
 | 
			
		||||
// MIT License
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
namespace ArduinoJson {
 | 
			
		||||
namespace TypeTraits {
 | 
			
		||||
 | 
			
		||||
// A meta-function that return the type T without the reference modifier.
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RemoveReference {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct RemoveReference<T&> {
 | 
			
		||||
  typedef T type;
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user