Skip to content

Commit

Permalink
Reduced memory consumption by not duplicating spaces and comments
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed Dec 29, 2016
1 parent 17801b2 commit 1f92154
Show file tree
Hide file tree
Showing 20 changed files with 594 additions and 285 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@ HEAD
----

* Added operator `==` to compare `JsonVariant` and strings (issue #402)
* Reduced memory consumption by not duplicating spaces and comments

v5.7.3
------
Expand Down
115 changes: 0 additions & 115 deletions include/ArduinoJson/Data/BlockJsonBuffer.hpp

This file was deleted.

27 changes: 27 additions & 0 deletions include/ArduinoJson/Data/StringFuncs.hpp
Expand Up @@ -30,6 +30,17 @@ template <typename TString>
struct StringFuncs<TString&> : StringFuncs<TString> {};

struct CharPtrFuncs {
class Iterator {
const char* _ptr;

public:
Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {}

char next() {
return *_ptr++;
}
};

static bool equals(const char* str, const char* expected) {
return strcmp(str, expected) == 0;
}
Expand Down Expand Up @@ -71,6 +82,10 @@ struct StdStringFuncs {
return static_cast<char*>(dup);
}

struct Iterator : CharPtrFuncs::Iterator {
Iterator(const TString& str) : CharPtrFuncs::Iterator(str.c_str()) {}
};

static bool equals(const TString& str, const char* expected) {
return str == expected;
}
Expand Down Expand Up @@ -99,6 +114,18 @@ struct StringFuncs<std::string> : StdStringFuncs<std::string> {};
#if ARDUINOJSON_ENABLE_PROGMEM
template <>
struct StringFuncs<const __FlashStringHelper*> {
class Iterator {
const char* _ptr;

public:
Iterator(const __FlashStringHelper* ptr)
: _ptr(reinterpret_cast<const char*>(ptr)) {}

char next() {
return pgm_read_byte_near(_ptr++);
}
};

static bool equals(const __FlashStringHelper* str, const char* expected) {
return strcmp_P(expected, (PGM_P)str) == 0;
}
Expand Down
28 changes: 14 additions & 14 deletions include/ArduinoJson/Deserialization/Comments.hpp
Expand Up @@ -12,51 +12,51 @@ namespace Internals {
template <typename TInput>
void skipSpacesAndComments(TInput& input) {
for (;;) {
switch (input.peek()) {
switch (input.current()) {
// spaces
case ' ':
case '\t':
case '\r':
case '\n':
input.skip();
input.move();
continue;

// comments
case '/':
switch (input.peekNext()) {
switch (input.next()) {
// C-style block comment
case '*':
input.skip(); // skip '/'
input.skip(); // skip '*'
input.move(); // skip '/'
input.move(); // skip '*'
for (;;) {
switch (input.peek()) {
switch (input.current()) {
case '\0':
return;
case '*':
input.skip(); // skip '*'
if (input.peek() == '/') {
input.skip(); // skip '/'
input.move(); // skip '*'
if (input.current() == '/') {
input.move(); // skip '/'
return;
}
break;
default:
input.skip();
input.move();
}
}
break;

// C++-style line comment
case '/':
input.skip(); // skip '/'
input.move(); // skip '/'
for (;;) {
switch (input.peek()) {
switch (input.current()) {
case '\0':
return;
case '\n':
input.skip();
input.move();
return;
default:
input.skip();
input.move();
}
}
return;
Expand Down
49 changes: 43 additions & 6 deletions include/ArduinoJson/Deserialization/JsonParser.hpp
Expand Up @@ -18,12 +18,14 @@ 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, char *json, uint8_t nestingLimit)
JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer,
uint8_t nestingLimit)
: _buffer(buffer),
_reader(json),
_writer(json),
_reader(reader),
_writer(writer),
_nestingLimit(nestingLimit) {}

JsonArray &parseArray();
Expand All @@ -36,7 +38,9 @@ class JsonParser {
}

private:
static bool eat(StringReader &, char charToSkip);
JsonParser &operator=(const JsonParser &); // non-copiable

static bool eat(TReader &, char charToSkip);
FORCE_INLINE bool eat(char charToSkip) {
return eat(_reader, charToSkip);
}
Expand All @@ -63,9 +67,42 @@ class JsonParser {
}

JsonBuffer *_buffer;
StringReader _reader;
StringWriter _writer;
TReader _reader;
TWriter _writer;
uint8_t _nestingLimit;
};

template <typename TJsonBuffer, typename TString>
struct JsonParserBuilder {
typedef typename Internals::StringFuncs<TString>::Iterator InputIterator;
typedef JsonParser<StringReader<InputIterator>, TJsonBuffer &> TParser;

static TParser makeParser(TJsonBuffer *buffer, const TString &json,
uint8_t nestingLimit) {
return TParser(buffer, InputIterator(json), *buffer, nestingLimit);
}
};

template <typename TJsonBuffer>
struct JsonParserBuilder<TJsonBuffer, char *> {
typedef typename Internals::StringFuncs<char *>::Iterator InputIterator;
typedef JsonParser<StringReader<InputIterator>, StringWriter> TParser;

static TParser makeParser(TJsonBuffer *buffer, char *json,
uint8_t nestingLimit) {
return TParser(buffer, InputIterator(json), json, nestingLimit);
}
};

template <typename TJsonBuffer, typename TChar, size_t N>
struct JsonParserBuilder<TJsonBuffer, TChar[N]>
: JsonParserBuilder<TJsonBuffer, TChar *> {};

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);
}
}
}

0 comments on commit 1f92154

Please sign in to comment.