Skip to content

Commit

Permalink
Fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed Oct 29, 2018
1 parent c537c62 commit aaeaa9f
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 43 deletions.
7 changes: 7 additions & 0 deletions src/ArduinoJson/Data/VariantFunctions.hpp
Expand Up @@ -171,6 +171,13 @@ inline bool variantSetString(JsonVariantData* var, T value, MemoryPool* pool) {
}
}

inline bool variantSetOwnedString(JsonVariantData* var, StringSlot* slot) {
if (!var) return false;
var->type = JSON_OWNED_STRING;
var->content.asOwnedString = slot;
return true;
}

inline bool variantSetString(JsonVariantData* var, const char* value) {
if (!var) return false;
var->type = JSON_LINKED_STRING;
Expand Down
23 changes: 12 additions & 11 deletions src/ArduinoJson/Json/JsonDeserializer.hpp
Expand Up @@ -18,6 +18,7 @@ template <typename TReader, typename TStringStorage>
class JsonDeserializer {
typedef typename remove_reference<TStringStorage>::type::StringBuilder
StringBuilder;
typedef typename StringBuilder::StringType StringType;

public:
JsonDeserializer(MemoryPool &memoryPool, TReader reader,
Expand Down Expand Up @@ -124,7 +125,7 @@ class JsonDeserializer {
// Read each key value pair
for (;;) {
// Parse key
StringInMemoryPool key;
StringType key;
err = parseKey(key);
if (err) return err;

Expand Down Expand Up @@ -165,7 +166,7 @@ class JsonDeserializer {
}
}

DeserializationError parseKey(StringInMemoryPool &key) {
DeserializationError parseKey(StringType &key) {
if (isQuote(current())) {
return parseQuotedString(key);
} else {
Expand All @@ -174,15 +175,15 @@ class JsonDeserializer {
}

DeserializationError parseStringValue(JsonVariant variant) {
StringInMemoryPool value;
StringType value;
DeserializationError err = parseQuotedString(value);
if (err) return err;
variant.set(value);
return DeserializationError::Ok;
}

DeserializationError parseQuotedString(StringInMemoryPool &result) {
StringBuilder str = _stringStorage.startString();
DeserializationError parseQuotedString(StringType &result) {
StringBuilder builder = _stringStorage.startString();
const char stopChar = current();

move();
Expand All @@ -203,31 +204,31 @@ class JsonDeserializer {
move();
}

str.append(c);
builder.append(c);
}

result = str.complete();
result = builder.complete();
if (result.isNull()) return DeserializationError::NoMemory;
return DeserializationError::Ok;
}

DeserializationError parseNonQuotedString(StringInMemoryPool &result) {
StringBuilder str = _stringStorage.startString();
DeserializationError parseNonQuotedString(StringType &result) {
StringBuilder builder = _stringStorage.startString();

char c = current();
if (c == '\0') return DeserializationError::IncompleteInput;

if (canBeInNonQuotedString(c)) { // no quotes
do {
move();
str.append(c);
builder.append(c);
c = current();
} while (canBeInNonQuotedString(c));
} else {
return DeserializationError::InvalidInput;
}

result = str.complete();
result = builder.complete();
if (result.isNull()) return DeserializationError::NoMemory;
return DeserializationError::Ok;
}
Expand Down
6 changes: 5 additions & 1 deletion src/ArduinoJson/JsonObject.hpp
Expand Up @@ -256,7 +256,11 @@ class JsonObject : public JsonObjectProxy<JsonObjectData>, public Visitable {
return set_impl(makeString(key));
}

FORCE_INLINE JsonVariant set(const StringInMemoryPool& key) const {
FORCE_INLINE JsonVariant set(StringInMemoryPool key) const {
return set_impl(key);
}

FORCE_INLINE JsonVariant set(ZeroTerminatedRamStringConst key) const {
return set_impl(key);
}

Expand Down
16 changes: 4 additions & 12 deletions src/ArduinoJson/JsonVariant.hpp
Expand Up @@ -204,8 +204,11 @@ class JsonVariant : public JsonVariantProxy<JsonVariantData>,
return variantSetString(_data, value);
}

// set(const char*);
// for internal use only
FORCE_INLINE bool set(StringInMemoryPool value) const {
return variantSetOwnedString(_data, value.slot());
}
FORCE_INLINE bool set(ZeroTerminatedRamStringConst value) const {
return variantSetString(_data, value.c_str());
}

Expand Down Expand Up @@ -323,15 +326,4 @@ class JsonVariantConst : public JsonVariantProxy<const JsonVariantData>,
return JsonVariantConst(objectGet(variantAsObject(_data), makeString(key)));
}
};

class JsonVariantLocal : public JsonVariant {
public:
explicit JsonVariantLocal(MemoryPool *memoryPool)
: JsonVariant(memoryPool, &_localData) {
_localData.type = JSON_NULL;
}

private:
JsonVariantData _localData;
};
} // namespace ARDUINOJSON_NAMESPACE
7 changes: 4 additions & 3 deletions src/ArduinoJson/Memory/StringBuilder.hpp
Expand Up @@ -11,6 +11,8 @@ namespace ARDUINOJSON_NAMESPACE {

class StringBuilder {
public:
typedef StringInMemoryPool StringType;

explicit StringBuilder(MemoryPool* parent) : _parent(parent) {
_slot = _parent->allocString(0);
}
Expand All @@ -19,10 +21,9 @@ class StringBuilder {
_slot = _parent->append(_slot, c);
}

StringInMemoryPool complete() {
StringType complete() {
_slot = _parent->append(_slot, 0);
if (!_slot) return 0;
return _slot->value;
return _slot;
}

private:
Expand Down
50 changes: 42 additions & 8 deletions src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
Expand Up @@ -17,6 +17,7 @@ template <typename TReader, typename TStringStorage>
class MsgPackDeserializer {
typedef typename remove_reference<TStringStorage>::type::StringBuilder
StringBuilder;
typedef typename StringBuilder::StringType StringType;

public:
MsgPackDeserializer(MemoryPool &memoryPool, TReader reader,
Expand Down Expand Up @@ -220,16 +221,29 @@ class MsgPackDeserializer {
return readString(variant, size);
}

template <typename T>
DeserializationError readString(StringType &str) {
T size;
if (!readInteger(size)) return DeserializationError::IncompleteInput;
return readString(str, size);
}

DeserializationError readString(JsonVariant variant, size_t n) {
StringBuilder str = _stringStorage.startString();
StringType s;
DeserializationError err = readString(s, n);
if (!err) variant.set(s);
return err;
}

DeserializationError readString(StringType &s, size_t n) {
StringBuilder builder = _stringStorage.startString();
for (; n; --n) {
uint8_t c;
if (!readBytes(c)) return DeserializationError::IncompleteInput;
str.append(static_cast<char>(c));
builder.append(static_cast<char>(c));
}
StringInMemoryPool s = str.complete();
s = builder.complete();
if (s.isNull()) return DeserializationError::NoMemory;
variant.set(s);
return DeserializationError::Ok;
}

Expand Down Expand Up @@ -278,12 +292,11 @@ class MsgPackDeserializer {
if (_nestingLimit == 0) return DeserializationError::TooDeep;
--_nestingLimit;
for (; n; --n) {
JsonVariantLocal key(_memoryPool);
DeserializationError err = parse(key);
StringType key;
DeserializationError err = parseKey(key);
if (err) return err;
if (!key.is<char *>()) return DeserializationError::NotSupported;

JsonVariant value = object.set(StringInMemoryPool(key.as<char *>()));
JsonVariant value = object.set(key);
if (value.isInvalid()) return DeserializationError::NoMemory;

err = parse(value);
Expand All @@ -293,6 +306,27 @@ class MsgPackDeserializer {
return DeserializationError::Ok;
}

DeserializationError parseKey(StringType &key) {
uint8_t code;
if (!readByte(code)) return DeserializationError::IncompleteInput;

if ((code & 0xe0) == 0xa0) return readString(key, code & 0x1f);

switch (code) {
case 0xd9:
return readString<uint8_t>(key);

case 0xda:
return readString<uint16_t>(key);

case 0xdb:
return readString<uint32_t>(key);

default:
return DeserializationError::NotSupported;
}
}

MemoryPool *_memoryPool;
TReader _reader;
TStringStorage _stringStorage;
Expand Down
4 changes: 3 additions & 1 deletion src/ArduinoJson/StringStorage/StringMover.hpp
Expand Up @@ -11,13 +11,15 @@ class StringMover {
public:
class StringBuilder {
public:
typedef ZeroTerminatedRamStringConst StringType;

StringBuilder(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}

void append(char c) {
*(*_writePtr)++ = TChar(c);
}

StringInMemoryPool complete() const {
StringType complete() const {
*(*_writePtr)++ = 0;
return reinterpret_cast<const char*>(_startPtr);
}
Expand Down
38 changes: 35 additions & 3 deletions src/ArduinoJson/Strings/StringInMemoryPool.hpp
Expand Up @@ -4,13 +4,45 @@

#pragma once

#include "ZeroTerminatedRamStringConst.hpp"
#include <string.h>
#include "../Memory/StringSlot.hpp"

namespace ARDUINOJSON_NAMESPACE {

class StringInMemoryPool : public ZeroTerminatedRamStringConst {
class StringInMemoryPool {
public:
StringInMemoryPool(const char* str = 0) : ZeroTerminatedRamStringConst(str) {}
StringInMemoryPool(StringSlot* s = 0) : _slot(s) {}

bool equals(const char* expected) const {
if (!_slot) return expected == 0;
const char* actual = _slot->value;
if (actual == expected) return true;
return strcmp(actual, expected) == 0;
}

bool isNull() const {
return !_slot;
}

template <typename TMemoryPool>
StringSlot* save(TMemoryPool*) const {
return _slot;
}

size_t size() const {
return _slot->size;
}

StringSlot* slot() const {
return _slot;
}

const char* c_str() const {
return _slot->value;
}

protected:
StringSlot* _slot;
};

} // namespace ARDUINOJSON_NAMESPACE
2 changes: 1 addition & 1 deletion src/ArduinoJson/Strings/ZeroTerminatedRamStringConst.hpp
Expand Up @@ -11,7 +11,7 @@ namespace ARDUINOJSON_NAMESPACE {

class ZeroTerminatedRamStringConst {
public:
ZeroTerminatedRamStringConst(const char* str) : _str(str) {}
ZeroTerminatedRamStringConst(const char* str = 0) : _str(str) {}

bool equals(const char* expected) const {
const char* actual = _str;
Expand Down
4 changes: 1 addition & 3 deletions test/JsonObject/copy.cpp
Expand Up @@ -44,9 +44,7 @@ TEST_CASE("JsonObject::copyFrom()") {

obj2.copyFrom(obj1);

CAPTURE(obj1);
CAPTURE(obj2);
CHECK(doc1.memoryUsage() == doc2.memoryUsage());
REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
REQUIRE(obj2["hello"] == std::string("world"));
}

Expand Down

0 comments on commit aaeaa9f

Please sign in to comment.