forked from bblanchon/ArduinoJson
Extracted the class Latch
also fixed a buffer overrun and reduced the code size
This commit is contained in:
@ -445,6 +445,15 @@ TEST_CASE("Filtering") {
|
|||||||
"[]",
|
"[]",
|
||||||
JSON_ARRAY_SIZE(0)
|
JSON_ARRAY_SIZE(0)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// supports back-slash at the end of skipped string
|
||||||
|
"\"hell\\",
|
||||||
|
"false",
|
||||||
|
1,
|
||||||
|
DeserializationError::IncompleteInput,
|
||||||
|
"null",
|
||||||
|
0
|
||||||
|
},
|
||||||
}; // clang-format on
|
}; // clang-format on
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(testCases) / sizeof(testCases[0]); i++) {
|
for (size_t i = 0; i < sizeof(testCases) / sizeof(testCases[0]); i++) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <ArduinoJson/Deserialization/deserialize.hpp>
|
#include <ArduinoJson/Deserialization/deserialize.hpp>
|
||||||
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
||||||
|
#include <ArduinoJson/Json/Latch.hpp>
|
||||||
#include <ArduinoJson/Json/Utf16.hpp>
|
#include <ArduinoJson/Json/Utf16.hpp>
|
||||||
#include <ArduinoJson/Json/Utf8.hpp>
|
#include <ArduinoJson/Json/Utf8.hpp>
|
||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||||
@ -24,20 +25,15 @@ class JsonDeserializer {
|
|||||||
JsonDeserializer(MemoryPool &pool, TReader reader,
|
JsonDeserializer(MemoryPool &pool, TReader reader,
|
||||||
TStringStorage stringStorage, uint8_t nestingLimit)
|
TStringStorage stringStorage, uint8_t nestingLimit)
|
||||||
: _pool(&pool),
|
: _pool(&pool),
|
||||||
_reader(reader),
|
|
||||||
_stringStorage(stringStorage),
|
_stringStorage(stringStorage),
|
||||||
_nestingLimit(nestingLimit),
|
_nestingLimit(nestingLimit),
|
||||||
_loaded(false) {
|
_latch(reader) {}
|
||||||
#ifdef ARDUINOJSON_DEBUG
|
|
||||||
_ended = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TFilter>
|
template <typename TFilter>
|
||||||
DeserializationError parse(VariantData &variant, TFilter filter) {
|
DeserializationError parse(VariantData &variant, TFilter filter) {
|
||||||
DeserializationError err = parseVariant(variant, filter);
|
DeserializationError err = parseVariant(variant, filter);
|
||||||
|
|
||||||
if (!err && _current != 0 && !variant.isEnclosed()) {
|
if (!err && _latch.last() != 0 && !variant.isEnclosed()) {
|
||||||
// We don't detect trailing characters earlier, so we need to check now
|
// We don't detect trailing characters earlier, so we need to check now
|
||||||
err = DeserializationError::InvalidInput;
|
err = DeserializationError::InvalidInput;
|
||||||
}
|
}
|
||||||
@ -49,23 +45,14 @@ class JsonDeserializer {
|
|||||||
JsonDeserializer &operator=(const JsonDeserializer &); // non-copiable
|
JsonDeserializer &operator=(const JsonDeserializer &); // non-copiable
|
||||||
|
|
||||||
char current() {
|
char current() {
|
||||||
if (!_loaded) {
|
return _latch.current();
|
||||||
ARDUINOJSON_ASSERT(!_ended);
|
|
||||||
int c = _reader.read();
|
|
||||||
#ifdef ARDUINOJSON_DEBUG
|
|
||||||
if (c <= 0) _ended = true;
|
|
||||||
#endif
|
|
||||||
_current = static_cast<char>(c > 0 ? c : 0);
|
|
||||||
_loaded = true;
|
|
||||||
}
|
|
||||||
return _current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void move() {
|
void move() {
|
||||||
_loaded = false;
|
_latch.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool eat(char charToSkip) {
|
bool eat(char charToSkip) {
|
||||||
if (current() != charToSkip) return false;
|
if (current() != charToSkip) return false;
|
||||||
move();
|
move();
|
||||||
return true;
|
return true;
|
||||||
@ -391,7 +378,9 @@ class JsonDeserializer {
|
|||||||
move();
|
move();
|
||||||
if (c == stopChar) break;
|
if (c == stopChar) break;
|
||||||
if (c == '\0') return DeserializationError::IncompleteInput;
|
if (c == '\0') return DeserializationError::IncompleteInput;
|
||||||
if (c == '\\') _reader.read();
|
if (c == '\\') {
|
||||||
|
if (current() != '\0') move();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeserializationError::Ok;
|
return DeserializationError::Ok;
|
||||||
@ -548,14 +537,9 @@ class JsonDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MemoryPool *_pool;
|
MemoryPool *_pool;
|
||||||
TReader _reader;
|
|
||||||
TStringStorage _stringStorage;
|
TStringStorage _stringStorage;
|
||||||
uint8_t _nestingLimit;
|
uint8_t _nestingLimit;
|
||||||
char _current;
|
Latch<TReader> _latch;
|
||||||
bool _loaded;
|
|
||||||
#ifdef ARDUINOJSON_DEBUG
|
|
||||||
bool _ended;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// deserializeJson(JsonDocument&, const std::string&, ...)
|
// deserializeJson(JsonDocument&, const std::string&, ...)
|
||||||
|
54
src/ArduinoJson/Json/Latch.hpp
Normal file
54
src/ArduinoJson/Json/Latch.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename TReader>
|
||||||
|
class Latch {
|
||||||
|
public:
|
||||||
|
Latch(TReader reader) : _reader(reader), _loaded(false) {
|
||||||
|
#ifdef ARDUINOJSON_DEBUG
|
||||||
|
_ended = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
_loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int last() const {
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE char current() {
|
||||||
|
if (!_loaded) {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void load() {
|
||||||
|
ARDUINOJSON_ASSERT(!_ended);
|
||||||
|
int c = _reader.read();
|
||||||
|
#ifdef ARDUINOJSON_DEBUG
|
||||||
|
if (c <= 0) _ended = true;
|
||||||
|
#endif
|
||||||
|
_current = static_cast<char>(c > 0 ? c : 0);
|
||||||
|
_loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TReader _reader;
|
||||||
|
char _current;
|
||||||
|
bool _loaded;
|
||||||
|
#ifdef ARDUINOJSON_DEBUG
|
||||||
|
bool _ended;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
Reference in New Issue
Block a user