Improved deserializeMsgPack() speed by reading several bytes at once

This commit is contained in:
Benoit Blanchon
2019-10-14 12:02:26 +02:00
parent fd8f4eb3a6
commit 16fe3c0acc
11 changed files with 286 additions and 50 deletions

View File

@ -23,6 +23,10 @@ struct ArduinoStreamReader {
char c;
return _stream.readBytes(&c, 1) ? c : -1;
}
size_t readBytes(char* buffer, size_t length) {
return _stream.readBytes(buffer, length);
}
};
inline ArduinoStreamReader makeReader(Stream& input) {

View File

@ -4,6 +4,7 @@
#pragma once
#include <ArduinoJson/Deserialization/IteratorReader.hpp>
#include <ArduinoJson/Namespace.hpp>
namespace ARDUINOJSON_NAMESPACE {
@ -28,22 +29,17 @@ class UnsafeCharPointerReader {
int read() {
return static_cast<unsigned char>(*_ptr++);
}
size_t readBytes(char* buffer, size_t length) {
for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++;
return length;
}
};
class SafeCharPointerReader {
const char* _ptr;
const char* _end;
class SafeCharPointerReader : public IteratorReader<const char*> {
public:
explicit SafeCharPointerReader(const char* ptr, size_t len)
: _ptr(ptr ? ptr : reinterpret_cast<const char*>("")), _end(_ptr + len) {}
int read() {
if (_ptr < _end)
return static_cast<unsigned char>(*_ptr++);
else
return -1;
}
: IteratorReader<const char*>(ptr, ptr + len) {}
};
template <typename TChar>

View File

@ -19,6 +19,12 @@ class UnsafeFlashStringReader {
int read() {
return pgm_read_byte(_ptr++);
}
size_t readBytes(char* buffer, size_t length) {
memcpy_P(buffer, _ptr, length);
_ptr += length;
return length;
}
};
class SafeFlashStringReader {
@ -35,6 +41,14 @@ class SafeFlashStringReader {
else
return -1;
}
size_t readBytes(char* buffer, size_t length) {
size_t available = static_cast<size_t>(_end - _ptr);
if (available < length) length = available;
memcpy_P(buffer, _ptr, length);
_ptr += length;
return length;
}
};
inline UnsafeFlashStringReader makeReader(const __FlashStringHelper* input) {

View File

@ -22,6 +22,12 @@ class IteratorReader {
else
return -1;
}
size_t readBytes(char* buffer, size_t length) {
size_t i = 0;
while (i < length && _ptr < _end) buffer[i++] = *_ptr++;
return i;
}
};
template <typename TInput>

View File

@ -24,6 +24,11 @@ class StdStreamReader {
return _stream.get();
}
size_t readBytes(char* buffer, size_t length) {
_stream.read(buffer, static_cast<std::streamsize>(length));
return static_cast<size_t>(_stream.gcount());
}
private:
StdStreamReader& operator=(const StdStreamReader&); // Visual Studio C4512
};

View File

@ -142,10 +142,7 @@ class MsgPackDeserializer {
}
bool readBytes(uint8_t *p, size_t n) {
for (size_t i = 0; i < n; i++) {
if (!readByte(p[i])) return false;
}
return true;
return _reader.readBytes(reinterpret_cast<char *>(p), n) == n;
}
template <typename T>