Fixed ignored Stream timeout and made sure we don't read more that necessary (issue #422)

This commit is contained in:
Benoit Blanchon
2017-01-22 10:31:05 +01:00
parent fb554071dc
commit cc8c0472ca
10 changed files with 89 additions and 71 deletions

View File

@@ -17,15 +17,35 @@ namespace ArduinoJson {
namespace Internals {
struct ArduinoStreamTraits {
class Iterator {
class Reader {
Stream& _stream;
char _current, _next;
public:
Iterator(Stream& stream) : _stream(stream) {}
Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {}
void move() {
_current = _next;
_next = 0;
}
char current() {
if (!_current) _current = read();
return _current;
}
char next() {
int n = _stream.read();
return n >= 0 ? static_cast<char>(n) : '\0';
// assumes that current() has been called
if (!_next) _next = read();
return _next;
}
private:
char read() {
// don't use _stream.read() as it ignores the timeout
char c = 0;
_stream.readBytes(&c, 1);
return c;
}
};
};

View File

@@ -11,16 +11,22 @@ namespace ArduinoJson {
namespace Internals {
struct CharPointerTraits {
class Iterator {
class Reader {
const char* _ptr;
public:
Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {}
Reader(const char* ptr) : _ptr(ptr ? ptr : "") {}
char next() {
char c = *_ptr;
if (c) ++_ptr;
return c;
void move() {
++_ptr;
}
char current() const {
return _ptr[0];
}
char next() const {
return _ptr[1];
}
};

View File

@@ -11,15 +11,23 @@ namespace ArduinoJson {
namespace Internals {
template <>
struct StringTraits<const __FlashStringHelper*, void> {
class Iterator {
class Reader {
const char* _ptr;
public:
Iterator(const __FlashStringHelper* ptr)
Reader(const __FlashStringHelper* ptr)
: _ptr(reinterpret_cast<const char*>(ptr)) {}
char next() {
return pgm_read_byte_near(_ptr++);
void move() {
_ptr++;
}
char current() const {
return pgm_read_byte_near(_ptr);
}
char next() const {
return pgm_read_byte_near(_ptr + 1);
}
};

View File

@@ -16,18 +16,35 @@ namespace ArduinoJson {
namespace Internals {
struct StdStreamTraits {
class Iterator {
class Reader {
std::istream& _stream;
char _current, _next;
public:
Iterator(std::istream& stream) : _stream(stream) {}
Reader(std::istream& stream) : _stream(stream), _current(0), _next(0) {}
void move() {
_current = _next;
_next = 0;
}
char current() {
if (!_current) _current = read();
return _current;
}
char next() {
return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
// assumes that current() has been called
if (!_next) _next = read();
return _next;
}
private:
Iterator& operator=(const Iterator&); // Visual Studio C4512
Reader& operator=(const Reader&); // Visual Studio C4512
char read() {
return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
}
};
};

View File

@@ -29,8 +29,8 @@ struct StdStringTraits {
return static_cast<char*>(dup);
}
struct Iterator : CharPointerTraits::Iterator {
Iterator(const TString& str) : CharPointerTraits::Iterator(str.c_str()) {}
struct Reader : CharPointerTraits::Reader {
Reader(const TString& str) : CharPointerTraits::Reader(str.c_str()) {}
};
static bool equals(const TString& str, const char* expected) {