mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-03 13:46:46 +02:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
4e9f0b2e2e | |||
223f14710d | |||
f7ae91b85d | |||
445dff499b | |||
9afa05e2f4 | |||
c3e1677b7d | |||
024976cda2 | |||
df541a2a22 | |||
f2ef338cb8 | |||
8c6f64c111 | |||
5a16b2117b | |||
71edcaf20f | |||
ac89d91db5 |
@ -93,11 +93,11 @@ matrix:
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake SANITIZE=address
|
||||
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.12 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=platformio BOARD=uno
|
||||
- env: SCRIPT=platformio BOARD=due
|
||||
- env: SCRIPT=platformio BOARD=esp01
|
||||
- env: SCRIPT=platformio BOARD=teensy31
|
||||
#- env: SCRIPT=platformio BOARD=teensy31C
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
|
@ -5,4 +5,4 @@
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include "include/ArduinoJson.h"
|
||||
#include "src/ArduinoJson.h"
|
||||
|
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,6 +1,18 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v5.9.0
|
||||
------
|
||||
|
||||
* Added `JsonArray::remove(iterator)` (issue #479)
|
||||
* Added `JsonObject::remove(iterator)`
|
||||
* Renamed `JsonArray::removeAt(size_t)` into `remove(size_t)`
|
||||
* Renamed folder `include/` to `src/`
|
||||
* Fixed warnings `floating constant exceeds range of float`and `floating constant truncated to zero` (issue #483)
|
||||
* Removed `Print` class and converted `printTo()` to a template method (issue #276)
|
||||
* Removed example `IndentedPrintExample.ino`
|
||||
* Now compatible with Particle 0.6.1, thanks to Jacob Nite (issue #294 and PR #461 by @foodbag)
|
||||
|
||||
v5.8.4
|
||||
------
|
||||
|
||||
|
@ -10,12 +10,10 @@ project(ArduinoJson)
|
||||
|
||||
enable_testing()
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
if(${COVERAGE})
|
||||
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
add_subdirectory(third-party/catch)
|
||||
add_subdirectory(test)
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 5.8.4.{build}
|
||||
version: 5.9.0.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
@ -15,4 +15,4 @@ before_build:
|
||||
build_script:
|
||||
- cmake --build . --config %CONFIGURATION%
|
||||
test_script:
|
||||
- ctest -V .
|
||||
- ctest --output-on-failure .
|
||||
|
@ -1,35 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial) {
|
||||
// wait serial port initialization
|
||||
}
|
||||
|
||||
IndentedPrint serial(Serial);
|
||||
serial.setTabSize(4);
|
||||
|
||||
serial.println("This is at indentation 0");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 1");
|
||||
serial.println("This is also at indentation 1");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 2");
|
||||
|
||||
serial.unindent();
|
||||
serial.unindent();
|
||||
serial.println("This is back at indentation 0");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
# CAUTION: this file is invoked by https://github.com/google/oss-fuzz
|
||||
|
||||
CXXFLAGS += -I../include
|
||||
CXXFLAGS += -I../src
|
||||
|
||||
all: \
|
||||
$(OUT)/json_fuzzer \
|
||||
$(OUT)/json_fuzzer_seed_corpus.zip \
|
||||
$(OUT)/json_fuzzer.options
|
||||
|
||||
$(OUT)/json_fuzzer: fuzzer.cpp $(shell find ../include -type f)
|
||||
$(OUT)/json_fuzzer: fuzzer.cpp $(shell find ../src -type f)
|
||||
$(CXX) $(CXXFLAGS) $< -o$@ $(LIB_FUZZING_ENGINE)
|
||||
|
||||
$(OUT)/json_fuzzer_seed_corpus.zip: seed_corpus/*
|
||||
|
@ -1,44 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
// This class reproduces Arduino's Print class
|
||||
class Print {
|
||||
public:
|
||||
virtual ~Print() {}
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
|
||||
size_t print(const char* s) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
n += write(static_cast<uint8_t>(*s++));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t println() {
|
||||
size_t n = 0;
|
||||
n += write('\r');
|
||||
n += write('\n');
|
||||
return n;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A Print implementation that allows to write in a char[]
|
||||
class StaticStringBuilder : public Print {
|
||||
public:
|
||||
StaticStringBuilder(char *buf, size_t size)
|
||||
: buffer(buf), capacity(size - 1), length(0) {
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
if (length >= capacity) return 0;
|
||||
|
||||
buffer[length++] = c;
|
||||
buffer[length] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
char *buffer;
|
||||
size_t capacity;
|
||||
size_t length;
|
||||
};
|
||||
}
|
||||
}
|
@ -6,14 +6,14 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "5.8.4",
|
||||
"version": "5.9.0",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
},
|
||||
"exclude": [
|
||||
"fuzzing",
|
||||
"scripts",
|
||||
"src/ArduinoJson.h",
|
||||
"test",
|
||||
"third-party"
|
||||
],
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=5.8.4
|
||||
version=5.9.0
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=An efficient and elegant JSON library for Arduino.
|
||||
|
@ -12,7 +12,7 @@ rm -f $OUTPUT
|
||||
7z a $OUTPUT \
|
||||
ArduinoJson/CHANGELOG.md \
|
||||
ArduinoJson/examples \
|
||||
ArduinoJson/include \
|
||||
ArduinoJson/src \
|
||||
ArduinoJson/keywords.txt \
|
||||
ArduinoJson/library.properties \
|
||||
ArduinoJson/LICENSE.md \
|
||||
|
@ -39,6 +39,6 @@ process()
|
||||
|
||||
cd $(dirname $0)/../
|
||||
INCLUDED=()
|
||||
process include/ArduinoJson.h true > ../ArduinoJson-$TAG.h
|
||||
process src/ArduinoJson.h true > ../ArduinoJson-$TAG.h
|
||||
INCLUDED=()
|
||||
process include/ArduinoJson.hpp true > ../ArduinoJson-$TAG.hpp
|
||||
process src/ArduinoJson.hpp true > ../ArduinoJson-$TAG.hpp
|
@ -1,5 +0,0 @@
|
||||
CPPLINT="python third-party/cpplint/cpplint.py"
|
||||
FLAGS="--filter=-runtime/printf,-runtime/int,-readability/todo,-build/namespace,-runtime/references,-readability/streams"
|
||||
|
||||
cd ..
|
||||
$CPPLINT $FLAGS $(find include src test -regex ".*\.[hc]pp$")
|
@ -1,7 +0,0 @@
|
||||
cd ..
|
||||
FILES=$(find include src test -regex ".*\.[ch]pp$")
|
||||
|
||||
clang-format -style=Google -i $FILES
|
||||
|
||||
# insert newline at end of file
|
||||
sed -i -e '$a\' $FILES
|
@ -1,44 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
FILE=../bin/ArduinoJsonTests.exe
|
||||
MD5=""
|
||||
|
||||
file_changed() {
|
||||
[[ ! -f "$FILE" ]] && return 1
|
||||
NEW_MD5=$(md5sum $FILE)
|
||||
[[ "$MD5" == "$NEW_MD5" ]] && return 1
|
||||
MD5=$NEW_MD5
|
||||
return 0
|
||||
}
|
||||
|
||||
test_succeed() {
|
||||
echo -en "\007"{,}
|
||||
}
|
||||
|
||||
test_failed() {
|
||||
echo -en "\007"{,,,,,,,,,,,}
|
||||
}
|
||||
|
||||
run_tests() {
|
||||
$FILE
|
||||
case $? in
|
||||
0)
|
||||
test_succeed
|
||||
;;
|
||||
1)
|
||||
test_failed
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
while true
|
||||
do
|
||||
if file_changed
|
||||
then
|
||||
run_tests
|
||||
else
|
||||
sleep 2
|
||||
fi
|
||||
done
|
||||
|
||||
|
@ -27,4 +27,4 @@ fi
|
||||
|
||||
$CMAKE .
|
||||
$CMAKE --build .
|
||||
$CTEST -VV .
|
||||
$CTEST --output-on-failure .
|
||||
|
@ -7,8 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -48,6 +48,20 @@ class List {
|
||||
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);
|
||||
}
|
||||
@ -62,22 +76,8 @@ class List {
|
||||
return const_iterator(NULL);
|
||||
}
|
||||
|
||||
protected:
|
||||
node_type *addNewNode() {
|
||||
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 newNode;
|
||||
}
|
||||
|
||||
void removeNode(node_type *nodeToRemove) {
|
||||
void remove(iterator it) {
|
||||
node_type *nodeToRemove = it._node;
|
||||
if (!nodeToRemove) return;
|
||||
if (nodeToRemove == _firstNode) {
|
||||
_firstNode = nodeToRemove->next;
|
||||
@ -87,7 +87,10 @@ class List {
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
JsonBuffer *_buffer;
|
||||
|
||||
private:
|
||||
node_type *_firstNode;
|
||||
};
|
||||
}
|
@ -38,6 +38,14 @@ class ListConstIterator {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ListConstIterator<T> &operator+=(size_t distance) {
|
||||
while (_node && distance) {
|
||||
_node = _node->next;
|
||||
--distance;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const ListNode<T> *_node;
|
||||
};
|
@ -13,9 +13,14 @@
|
||||
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) {}
|
||||
|
||||
@ -39,6 +44,14 @@ class ListIterator {
|
||||
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);
|
||||
}
|
@ -111,16 +111,15 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
// Gets the value at the specified index.
|
||||
template <typename T>
|
||||
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
|
||||
node_type *node = findNode(index);
|
||||
return node ? node->content.as<T>()
|
||||
: Internals::JsonVariantDefault<T>::get();
|
||||
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 {
|
||||
node_type *node = findNode(index);
|
||||
return node ? node->content.is<T>() : false;
|
||||
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.
|
||||
@ -132,9 +131,10 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
JsonObject &createNestedObject();
|
||||
|
||||
// Removes element at specified index.
|
||||
void removeAt(size_t index) {
|
||||
removeNode(findNode(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.
|
||||
@ -197,29 +197,26 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
node_type *findNode(size_t index) const {
|
||||
node_type *node = _firstNode;
|
||||
while (node && index--) node = node->next;
|
||||
return node;
|
||||
#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) {
|
||||
node_type *node = findNode(index);
|
||||
if (!node) return false;
|
||||
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
|
||||
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) {
|
||||
node_type *node = addNewNode();
|
||||
if (!node) return false;
|
||||
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
|
||||
value);
|
||||
iterator it = Internals::List<JsonVariant>::add();
|
||||
if (it == end()) return false;
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
|
||||
}
|
||||
};
|
||||
|
@ -247,14 +247,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
bool>::type
|
||||
containsKey(const TString& key) const {
|
||||
return findNode<const TString&>(key) != NULL;
|
||||
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 findNode<const TString*>(key) != NULL;
|
||||
return findKey<const TString*>(key) != end();
|
||||
}
|
||||
|
||||
// Removes the specified key and the associated value.
|
||||
@ -265,15 +265,18 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
|
||||
void>::type
|
||||
remove(const TString& key) {
|
||||
removeNode(findNode<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) {
|
||||
removeNode(findNode<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.
|
||||
@ -286,41 +289,44 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
private:
|
||||
// Returns the list node that matches the specified key.
|
||||
template <typename TStringRef>
|
||||
node_type* findNode(TStringRef key) const {
|
||||
for (node_type* node = _firstNode; node; node = node->next) {
|
||||
if (Internals::StringTraits<TStringRef>::equals(key, node->content.key))
|
||||
return node;
|
||||
iterator findKey(TStringRef key) {
|
||||
iterator it;
|
||||
for (it = begin(); it != end(); ++it) {
|
||||
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
|
||||
}
|
||||
return NULL;
|
||||
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 {
|
||||
node_type* node = findNode<TStringRef>(key);
|
||||
return node ? node->content.value.as<TValue>()
|
||||
: Internals::JsonVariantDefault<TValue>::get();
|
||||
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) {
|
||||
node_type* node = findNode<TStringRef>(key);
|
||||
if (!node) {
|
||||
node = addNewNode();
|
||||
if (!node) return false;
|
||||
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, node->content.key, key);
|
||||
bool key_ok =
|
||||
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
|
||||
if (!key_ok) return false;
|
||||
}
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content.value,
|
||||
value);
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
|
||||
}
|
||||
|
||||
template <typename TStringRef, typename TValue>
|
||||
bool is_impl(TStringRef key) const {
|
||||
node_type* node = findNode<TStringRef>(key);
|
||||
return node ? node->content.value.is<TValue>() : false;
|
||||
const_iterator it = findKey<TStringRef>(key);
|
||||
return it != end() ? it->value.is<TValue>() : false;
|
||||
}
|
||||
|
||||
template <typename TStringRef>
|
@ -40,8 +40,8 @@ class JsonObject;
|
||||
// - a string (const char*)
|
||||
// - a reference to a JsonArray or JsonObject
|
||||
class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
friend void Internals::JsonSerializer::serialize(const JsonVariant &,
|
||||
JsonWriter &);
|
||||
template <typename Print>
|
||||
friend class Internals::JsonSerializer;
|
||||
|
||||
public:
|
||||
// Creates an uninitialized JsonVariant
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h> // for strcmp
|
||||
#include "./ctype.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
@ -7,17 +7,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A dummy Print implementation used in JsonPrintable::measureLength()
|
||||
class DummyPrint : public Print {
|
||||
class DummyPrint {
|
||||
public:
|
||||
virtual size_t write(uint8_t) {
|
||||
size_t print(char) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t print(const char* s) {
|
||||
return strlen(s);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../StringTraits/StringTraits.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
@ -15,15 +14,21 @@ namespace Internals {
|
||||
|
||||
// A Print implementation that allows to write in a String
|
||||
template <typename TString>
|
||||
class DynamicStringBuilder : public Print {
|
||||
class DynamicStringBuilder {
|
||||
public:
|
||||
DynamicStringBuilder(TString &str) : _str(str) {}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
StringTraits<TString>::append(_str, static_cast<char>(c));
|
||||
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 &);
|
||||
|
@ -7,15 +7,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
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.
|
||||
class IndentedPrint : public Print {
|
||||
template <typename Print>
|
||||
class IndentedPrint {
|
||||
public:
|
||||
explicit IndentedPrint(Print &p) : sink(&p) {
|
||||
level = 0;
|
||||
@ -23,14 +22,21 @@ class IndentedPrint : public Print {
|
||||
isNewLine = true;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
size_t print(char c) {
|
||||
size_t n = 0;
|
||||
if (isNewLine) n += writeTabs();
|
||||
n += sink->write(c);
|
||||
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++;
|
||||
@ -54,7 +60,7 @@ class IndentedPrint : public Print {
|
||||
|
||||
size_t writeTabs() {
|
||||
size_t n = 0;
|
||||
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
|
||||
for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
|
||||
return n;
|
||||
}
|
||||
|
@ -31,9 +31,12 @@ namespace Internals {
|
||||
template <typename T>
|
||||
class JsonPrintable {
|
||||
public:
|
||||
size_t printTo(Print &print) const {
|
||||
JsonWriter writer(print);
|
||||
JsonSerializer::serialize(downcast(), writer);
|
||||
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();
|
||||
}
|
||||
|
||||
@ -62,8 +65,9 @@ class JsonPrintable {
|
||||
return printTo(sb);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(IndentedPrint &print) const {
|
||||
Prettyfier p(print);
|
||||
template <typename Print>
|
||||
size_t prettyPrintTo(IndentedPrint<Print> &print) const {
|
||||
Prettyfier<Print> p(print);
|
||||
return printTo(p);
|
||||
}
|
||||
|
||||
@ -77,8 +81,11 @@ class JsonPrintable {
|
||||
return prettyPrintTo(buffer, N);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(Print &print) const {
|
||||
IndentedPrint indentedPrint = IndentedPrint(print);
|
||||
template <typename Print>
|
||||
typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
|
||||
size_t>::type
|
||||
prettyPrintTo(Print &print) const {
|
||||
IndentedPrint<Print> indentedPrint(print);
|
||||
return prettyPrintTo(indentedPrint);
|
||||
}
|
||||
|
@ -20,14 +20,15 @@ class JsonVariant;
|
||||
|
||||
namespace Internals {
|
||||
|
||||
template <typename Writer>
|
||||
class JsonSerializer {
|
||||
public:
|
||||
static void serialize(const JsonArray &, JsonWriter &);
|
||||
static void serialize(const JsonArraySubscript &, JsonWriter &);
|
||||
static void serialize(const JsonObject &, JsonWriter &);
|
||||
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> &, JsonWriter &);
|
||||
static void serialize(const JsonVariant &, JsonWriter &);
|
||||
static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
|
||||
static void serialize(const JsonVariant &, Writer &);
|
||||
};
|
||||
}
|
||||
}
|
@ -14,8 +14,9 @@
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "JsonSerializer.hpp"
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonArray& array, JsonWriter& writer) {
|
||||
template <typename Writer>
|
||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
|
||||
const JsonArray& array, Writer& writer) {
|
||||
writer.beginArray();
|
||||
|
||||
JsonArray::const_iterator it = array.begin();
|
||||
@ -31,13 +32,15 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
writer.endArray();
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonArraySubscript& arraySubscript, JsonWriter& writer) {
|
||||
template <typename Writer>
|
||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
|
||||
const JsonArraySubscript& arraySubscript, Writer& writer) {
|
||||
serialize(arraySubscript.as<JsonVariant>(), writer);
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonObject& object, JsonWriter& writer) {
|
||||
template <typename Writer>
|
||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
|
||||
const JsonObject& object, Writer& writer) {
|
||||
writer.beginObject();
|
||||
|
||||
JsonObject::const_iterator it = object.begin();
|
||||
@ -55,14 +58,16 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
template <typename TKey>
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) {
|
||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
|
||||
const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) {
|
||||
serialize(objectSubscript.template as<JsonVariant>(), writer);
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonVariant& variant, JsonWriter& writer) {
|
||||
template <typename Writer>
|
||||
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
|
||||
const JsonVariant& variant, Writer& writer) {
|
||||
switch (variant._type) {
|
||||
case JSON_UNDEFINED:
|
||||
return;
|
@ -7,13 +7,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../Data/Encoding.hpp"
|
||||
#include "../Data/JsonFloat.hpp"
|
||||
#include "../Data/JsonInteger.hpp"
|
||||
#include "../Polyfills/attributes.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
#include "../Polyfills/normalize.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
@ -25,6 +25,7 @@ namespace Internals {
|
||||
// - 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) {}
|
||||
@ -150,7 +151,7 @@ class JsonWriter {
|
||||
_length += _sink.print(s);
|
||||
}
|
||||
void writeRaw(char c) {
|
||||
_length += _sink.write(c);
|
||||
_length += _sink.print(c);
|
||||
}
|
||||
|
||||
protected:
|
@ -13,19 +13,27 @@ namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Converts a compact JSON string into an indented one.
|
||||
class Prettyfier : public Print {
|
||||
template <typename Print>
|
||||
class Prettyfier {
|
||||
public:
|
||||
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
|
||||
explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) {
|
||||
_previousChar = 0;
|
||||
_inString = false;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
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
|
||||
|
||||
@ -33,15 +41,15 @@ class Prettyfier : public Print {
|
||||
return _previousChar == '{' || _previousChar == '[';
|
||||
}
|
||||
|
||||
size_t handleStringChar(uint8_t c) {
|
||||
size_t handleStringChar(char c) {
|
||||
bool isQuote = c == '"' && _previousChar != '\\';
|
||||
|
||||
if (isQuote) _inString = false;
|
||||
|
||||
return _sink.write(c);
|
||||
return _sink.print(c);
|
||||
}
|
||||
|
||||
size_t handleMarkupChar(uint8_t c) {
|
||||
size_t handleMarkupChar(char c) {
|
||||
switch (c) {
|
||||
case '{':
|
||||
case '[':
|
||||
@ -65,31 +73,29 @@ class Prettyfier : public Print {
|
||||
}
|
||||
}
|
||||
|
||||
size_t writeBlockClose(uint8_t c) {
|
||||
size_t writeBlockClose(char c) {
|
||||
size_t n = 0;
|
||||
n += unindentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
n += _sink.print(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeBlockOpen(uint8_t c) {
|
||||
size_t writeBlockOpen(char c) {
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
n += _sink.print(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeColon() {
|
||||
size_t n = 0;
|
||||
n += _sink.write(':');
|
||||
n += _sink.write(' ');
|
||||
n += _sink.print(": ");
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeComma() {
|
||||
size_t n = 0;
|
||||
n += _sink.write(',');
|
||||
n += _sink.println();
|
||||
n += _sink.print(",\r\n");
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -97,14 +103,14 @@ class Prettyfier : public Print {
|
||||
_inString = true;
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write('"');
|
||||
n += _sink.print('"');
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeNormalChar(uint8_t c) {
|
||||
size_t writeNormalChar(char c) {
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
n += _sink.print(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -112,18 +118,18 @@ class Prettyfier : public Print {
|
||||
if (!inEmptyBlock()) return 0;
|
||||
|
||||
_sink.indent();
|
||||
return _sink.println();
|
||||
return _sink.print("\r\n");
|
||||
}
|
||||
|
||||
size_t unindentIfNeeded() {
|
||||
if (inEmptyBlock()) return 0;
|
||||
|
||||
_sink.unindent();
|
||||
return _sink.println();
|
||||
return _sink.print("\r\n");
|
||||
}
|
||||
|
||||
uint8_t _previousChar;
|
||||
IndentedPrint& _sink;
|
||||
char _previousChar;
|
||||
IndentedPrint<Print>& _sink;
|
||||
bool _inString;
|
||||
};
|
||||
}
|
39
src/ArduinoJson/Serialization/StaticStringBuilder.hpp
Normal file
39
src/ArduinoJson/Serialization/StaticStringBuilder.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#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 p - begin;
|
||||
}
|
||||
|
||||
private:
|
||||
char *end;
|
||||
char *p;
|
||||
};
|
||||
}
|
||||
}
|
@ -11,22 +11,25 @@
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
class StreamPrintAdapter : public Print {
|
||||
class StreamPrintAdapter {
|
||||
public:
|
||||
explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
_os << static_cast<char>(c);
|
||||
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&);
|
@ -43,6 +43,10 @@ struct StdStringTraits {
|
||||
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;
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
#include "../Polyfills/math.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
@ -16,7 +17,7 @@ namespace TypeTraits {
|
||||
template <typename T, size_t = sizeof(T)>
|
||||
struct FloatTraits {};
|
||||
|
||||
#ifndef ARDUINO_ARCH_AVR // double is 32 bits, so 1e64 gives a warning
|
||||
#if !defined(__SIZEOF_DOUBLE__) || __SIZEOF_DOUBLE__ >= 8
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 8 /*64bits*/> {
|
||||
typedef int64_t mantissa_type;
|
@ -5,13 +5,8 @@
|
||||
# https://bblanchon.github.io/ArduinoJson/
|
||||
# If you like this project, please add a star!
|
||||
|
||||
include(gtest.cmake)
|
||||
|
||||
file(GLOB TESTS_FILES *.hpp *.cpp)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
add_compile_options(
|
||||
-fno-exceptions
|
||||
-pedantic
|
||||
-Wall
|
||||
-Wcast-align
|
||||
@ -65,8 +60,13 @@ if(MSVC)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_executable(ArduinoJsonTests ${TESTS_FILES})
|
||||
target_include_directories(ArduinoJsonTests PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../include)
|
||||
target_link_libraries(ArduinoJsonTests gtest)
|
||||
|
||||
add_test(ArduinoJsonTests ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ArduinoJsonTests)
|
||||
add_subdirectory(DynamicJsonBuffer)
|
||||
add_subdirectory(IntegrationTests)
|
||||
add_subdirectory(JsonArray)
|
||||
add_subdirectory(JsonBuffer)
|
||||
add_subdirectory(JsonObject)
|
||||
add_subdirectory(JsonVariant)
|
||||
add_subdirectory(JsonWriter)
|
||||
add_subdirectory(Misc)
|
||||
add_subdirectory(Polyfills)
|
||||
add_subdirectory(StaticJsonBuffer)
|
@ -1,36 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#define ARDUINOJSON_ENABLE_DEPRECATED 1
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
TEST(Deprecated, asArray) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonVariant variant = jsonBuffer.createArray();
|
||||
ASSERT_TRUE(variant.asArray().success());
|
||||
}
|
||||
|
||||
TEST(Deprecated, asObject) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonVariant variant = jsonBuffer.createObject();
|
||||
ASSERT_TRUE(variant.asObject().success());
|
||||
}
|
||||
|
||||
TEST(Deprecated, asString) {
|
||||
JsonVariant variant = "hello";
|
||||
ASSERT_STREQ("hello", variant.asString());
|
||||
}
|
18
test/DynamicJsonBuffer/CMakeLists.txt
Normal file
18
test/DynamicJsonBuffer/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright Benoit Blanchon 2014-2017
|
||||
# MIT License
|
||||
#
|
||||
# Arduino JSON library
|
||||
# https://bblanchon.github.io/ArduinoJson/
|
||||
# If you like this project, please add a star!
|
||||
|
||||
add_executable(DynamicJsonBufferTests
|
||||
alloc.cpp
|
||||
createArray.cpp
|
||||
no_memory.cpp
|
||||
createObject.cpp
|
||||
strdup.cpp
|
||||
startString.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(DynamicJsonBufferTests catch)
|
||||
add_test(DynamicJsonBuffer DynamicJsonBufferTests)
|
45
test/DynamicJsonBuffer/alloc.cpp
Normal file
45
test/DynamicJsonBuffer/alloc.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
static bool isAligned(void* ptr) {
|
||||
const size_t mask = sizeof(void*) - 1;
|
||||
size_t addr = reinterpret_cast<size_t>(ptr);
|
||||
return (addr & mask) == 0;
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonBuffer::alloc()") {
|
||||
DynamicJsonBuffer buffer;
|
||||
|
||||
SECTION("InitialSizeIsZero") {
|
||||
REQUIRE(0 == buffer.size());
|
||||
}
|
||||
|
||||
SECTION("SizeIncreasesAfterAlloc") {
|
||||
buffer.alloc(1);
|
||||
REQUIRE(1U <= buffer.size());
|
||||
buffer.alloc(1);
|
||||
REQUIRE(2U <= buffer.size());
|
||||
}
|
||||
|
||||
SECTION("ReturnDifferentPointer") {
|
||||
void* p1 = buffer.alloc(1);
|
||||
void* p2 = buffer.alloc(2);
|
||||
REQUIRE(p1 != p2);
|
||||
}
|
||||
|
||||
SECTION("Alignment") {
|
||||
// make room for two but not three
|
||||
buffer = DynamicJsonBuffer(2 * sizeof(void*) + 1);
|
||||
|
||||
REQUIRE(isAligned(buffer.alloc(1))); // this on is aligned by design
|
||||
REQUIRE(isAligned(buffer.alloc(1))); // this one fits in the first block
|
||||
REQUIRE(isAligned(buffer.alloc(1))); // this one requires a new block
|
||||
}
|
||||
}
|
31
test/DynamicJsonBuffer/createArray.cpp
Normal file
31
test/DynamicJsonBuffer/createArray.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("DynamicJsonBuffer::createArray()") {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray &array = jsonBuffer.createArray();
|
||||
|
||||
SECTION("GrowsWithArray") {
|
||||
REQUIRE(JSON_ARRAY_SIZE(0) == jsonBuffer.size());
|
||||
|
||||
array.add("hello");
|
||||
REQUIRE(JSON_ARRAY_SIZE(1) == jsonBuffer.size());
|
||||
|
||||
array.add("world");
|
||||
REQUIRE(JSON_ARRAY_SIZE(2) == jsonBuffer.size());
|
||||
}
|
||||
|
||||
SECTION("CanAdd1000Values") {
|
||||
for (size_t i = 1; i <= 1000; i++) {
|
||||
array.add("hello");
|
||||
REQUIRE(array.size() == i);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,20 +6,20 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST(DynamicJsonBuffer_Object_Tests, GrowsWithObject) {
|
||||
TEST_CASE("DynamicJsonBuffer::createObject()") {
|
||||
DynamicJsonBuffer json;
|
||||
|
||||
JsonObject &obj = json.createObject();
|
||||
ASSERT_EQ(JSON_OBJECT_SIZE(0), json.size());
|
||||
REQUIRE(JSON_OBJECT_SIZE(0) == json.size());
|
||||
|
||||
obj["hello"] = 1;
|
||||
ASSERT_EQ(JSON_OBJECT_SIZE(1), json.size());
|
||||
REQUIRE(JSON_OBJECT_SIZE(1) == json.size());
|
||||
|
||||
obj["world"] = 2;
|
||||
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
||||
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
|
||||
|
||||
obj["world"] = 3; // <- same key, should not grow
|
||||
ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size());
|
||||
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
|
||||
}
|
50
test/DynamicJsonBuffer/no_memory.cpp
Normal file
50
test/DynamicJsonBuffer/no_memory.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright Benoit Blanchon 2014-2017
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://bblanchon.github.io/ArduinoJson/
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
struct NoMemoryAllocator {
|
||||
void* allocate(size_t) {
|
||||
return NULL;
|
||||
}
|
||||
void deallocate(void*) {}
|
||||
};
|
||||
|
||||
TEST_CASE("DynamicJsonBuffer no memory") {
|
||||
DynamicJsonBufferBase<NoMemoryAllocator> _jsonBuffer;
|
||||
|
||||
SECTION("FixCodeCoverage") {
|
||||
// call this function to fix code coverage
|
||||
NoMemoryAllocator().deallocate(NULL);
|
||||
}
|
||||
|
||||
SECTION("createArray()") {
|
||||
REQUIRE_FALSE(_jsonBuffer.createArray().success());
|
||||
}
|
||||
|
||||
SECTION("createObject()") {
|
||||
REQUIRE_FALSE(_jsonBuffer.createObject().success());
|
||||
}
|
||||
|
||||
SECTION("parseArray()") {
|
||||
char json[] = "[]";
|
||||
REQUIRE_FALSE(_jsonBuffer.parseArray(json).success());
|
||||
}
|
||||
|
||||
SECTION("parseObject()") {
|
||||
char json[] = "{}";
|
||||
REQUIRE_FALSE(_jsonBuffer.parseObject(json).success());
|
||||
}
|
||||
|
||||
SECTION("startString()") {
|
||||
DynamicJsonBufferBase<NoMemoryAllocator>::String str =
|
||||
_jsonBuffer.startString();
|
||||
str.append('!');
|
||||
REQUIRE(0 == str.c_str());
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user