mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 14:42:18 +03:00
compiling
This commit is contained in:
7
lib/ArduinoStreamUtils/src/StreamUtils.h
Normal file
7
lib/ArduinoStreamUtils/src/StreamUtils.h
Normal file
@@ -0,0 +1,7 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils.hpp"
|
||||
|
||||
using namespace StreamUtils;
|
||||
28
lib/ArduinoStreamUtils/src/StreamUtils.hpp
Normal file
28
lib/ArduinoStreamUtils/src/StreamUtils.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#include "StreamUtils/Clients/HammingClient.hpp"
|
||||
#include "StreamUtils/Clients/HammingDecodingClient.hpp"
|
||||
#include "StreamUtils/Clients/HammingEncodingClient.hpp"
|
||||
#include "StreamUtils/Clients/LoggingClient.hpp"
|
||||
#include "StreamUtils/Clients/ReadBufferingClient.hpp"
|
||||
#include "StreamUtils/Clients/ReadLoggingClient.hpp"
|
||||
#include "StreamUtils/Clients/WriteBufferingClient.hpp"
|
||||
#include "StreamUtils/Clients/WriteLoggingClient.hpp"
|
||||
#include "StreamUtils/Prints/BufferingPrint.hpp"
|
||||
#include "StreamUtils/Prints/HammingPrint.hpp"
|
||||
#include "StreamUtils/Prints/LoggingPrint.hpp"
|
||||
#include "StreamUtils/Prints/StringPrint.hpp"
|
||||
#include "StreamUtils/Streams/EepromStream.hpp"
|
||||
#include "StreamUtils/Streams/HammingDecodingStream.hpp"
|
||||
#include "StreamUtils/Streams/HammingEncodingStream.hpp"
|
||||
#include "StreamUtils/Streams/HammingStream.hpp"
|
||||
#include "StreamUtils/Streams/LoggingStream.hpp"
|
||||
#include "StreamUtils/Streams/ReadBufferingStream.hpp"
|
||||
#include "StreamUtils/Streams/ReadLoggingStream.hpp"
|
||||
#include "StreamUtils/Streams/ReadThrottlingStream.hpp"
|
||||
#include "StreamUtils/Streams/StringStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteBufferingStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteLoggingStream.hpp"
|
||||
#include "StreamUtils/Streams/WriteWaitingStream.hpp"
|
||||
57
lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp
Normal file
57
lib/ArduinoStreamUtils/src/StreamUtils/Buffers/CharArray.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> // size_t
|
||||
#include <string.h> // memcpy
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class CharArray {
|
||||
public:
|
||||
CharArray(size_t size, TAllocator allocator = TAllocator())
|
||||
: _allocator(allocator) {
|
||||
_data = reinterpret_cast<char *>(_allocator.allocate(size));
|
||||
_size = _data ? size : 0;
|
||||
}
|
||||
|
||||
CharArray(const CharArray &src) : CharArray(src._size, src._allocator) {
|
||||
if (_data != nullptr)
|
||||
memcpy(_data, src._data, _size);
|
||||
}
|
||||
|
||||
~CharArray() {
|
||||
_allocator.deallocate(_data);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return _size > 0;
|
||||
}
|
||||
|
||||
char *operator&() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
char &operator[](size_t i) {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
char operator[](size_t i) const {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
protected:
|
||||
TAllocator _allocator;
|
||||
char *_data;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,101 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "CharArray.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class CircularBuffer {
|
||||
public:
|
||||
CircularBuffer(size_t capacity, TAllocator allocator = TAllocator())
|
||||
: _data(capacity, allocator) {
|
||||
_begin = _end = _size = 0;
|
||||
}
|
||||
|
||||
CircularBuffer(const CircularBuffer &src)
|
||||
: CircularBuffer(src._data.size(), src._allocator) {
|
||||
if (_data) {
|
||||
_begin = src._begin;
|
||||
_end = src._end;
|
||||
_size = src._size;
|
||||
}
|
||||
}
|
||||
|
||||
size_t available() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_begin = _end = _size = 0;
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return _size == 0;
|
||||
}
|
||||
|
||||
bool isFull() const {
|
||||
return _size == _data.size();
|
||||
}
|
||||
|
||||
char peek() const {
|
||||
assert(_size > 0);
|
||||
return _data[_begin];
|
||||
}
|
||||
|
||||
char read() {
|
||||
assert(_size > 0);
|
||||
char result = _data[_begin];
|
||||
_begin = (_begin + 1) % _data.size();
|
||||
_size--;
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t readBytes(char *data, size_t size) {
|
||||
// don't read more that available
|
||||
if (size > _size)
|
||||
size = _size;
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
data[i] = read();
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) {
|
||||
assert(_size < _data.size());
|
||||
_data[_end] = data;
|
||||
_end = (_end + 1) % _data.size();
|
||||
_size++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *data, size_t size) {
|
||||
// don't read more that available
|
||||
size_t roomLeft = _data.size() - _size;
|
||||
if (size > roomLeft)
|
||||
size = roomLeft;
|
||||
|
||||
for (size_t i = 0; i < size; i++)
|
||||
write(data[i]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private:
|
||||
CharArray<TAllocator> _data;
|
||||
size_t _size;
|
||||
size_t _begin;
|
||||
size_t _end;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
111
lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp
Normal file
111
lib/ArduinoStreamUtils/src/StreamUtils/Buffers/LinearBuffer.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Helpers.hpp"
|
||||
#include "CharArray.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class LinearBuffer {
|
||||
public:
|
||||
LinearBuffer(size_t capacity, TAllocator allocator = TAllocator())
|
||||
: _data(capacity, allocator) {
|
||||
_begin = _data ? &_data : nullptr;
|
||||
_end = _begin;
|
||||
}
|
||||
|
||||
LinearBuffer(const LinearBuffer &src) : _data(src._data) {
|
||||
if (_data) {
|
||||
memcpy(&_data, src._begin, src.available());
|
||||
_begin = &_data;
|
||||
_end = &_data + src.available();
|
||||
} else {
|
||||
_begin = nullptr;
|
||||
_end = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
size_t available() const {
|
||||
return _end - _begin;
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_begin = _end = _data;
|
||||
}
|
||||
|
||||
bool isEmpty() const {
|
||||
return available() == 0;
|
||||
}
|
||||
|
||||
bool isFull() const {
|
||||
return available() == capacity();
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
char peek() const {
|
||||
return *_begin;
|
||||
}
|
||||
|
||||
char read() {
|
||||
return *_begin++;
|
||||
}
|
||||
|
||||
size_t readBytes(char *dstPtr, size_t dstSize) {
|
||||
size_t srcSize = available();
|
||||
size_t n = srcSize < dstSize ? srcSize : dstSize;
|
||||
memcpy(dstPtr, _begin, n);
|
||||
_begin += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) {
|
||||
assert(!isFull());
|
||||
*_end++ = data;
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *data, size_t size) {
|
||||
size_t roomLeft = capacity() - available();
|
||||
if (size > roomLeft)
|
||||
size = roomLeft;
|
||||
memcpy(_end, data, size);
|
||||
_end += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename TTarget> // Stream or Client
|
||||
void reloadFrom(TTarget &source, size_t size) {
|
||||
if (size > _data.size())
|
||||
size = _data.size();
|
||||
size_t n = readOrReadBytes(source, &_data, size);
|
||||
_begin = &_data;
|
||||
_end = &_data + n;
|
||||
}
|
||||
|
||||
void flushInto(Print &destination) {
|
||||
if (_begin != _end)
|
||||
destination.write(_begin, _end - _begin);
|
||||
_begin = _end = &_data;
|
||||
}
|
||||
|
||||
private:
|
||||
CharArray<TAllocator> _data;
|
||||
char *_begin;
|
||||
char *_end;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
105
lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp
Normal file
105
lib/ArduinoStreamUtils/src/StreamUtils/Clients/ClientProxy.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Streams/StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename ReadPolicy, typename WritePolicy, typename ConnectPolicy>
|
||||
class ClientProxy : public Client {
|
||||
public:
|
||||
explicit ClientProxy(Client &upstream, ReadPolicy reader = ReadPolicy(),
|
||||
WritePolicy writer = WritePolicy(),
|
||||
ConnectPolicy connection = ConnectPolicy())
|
||||
: _target(upstream),
|
||||
_reader(reader),
|
||||
_writer(Polyfills::move(writer)),
|
||||
_connection(connection) {}
|
||||
|
||||
ClientProxy(const ClientProxy &other)
|
||||
: _target(other._target),
|
||||
_reader(other._reader),
|
||||
_writer(other._writer),
|
||||
_connection(other._connection) {}
|
||||
|
||||
~ClientProxy() {
|
||||
_writer.implicitFlush(_target);
|
||||
}
|
||||
|
||||
// --- Print ---
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size) override {
|
||||
return _writer.write(_target, buffer, size);
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
return _writer.write(_target, data);
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
|
||||
// --- Stream ---
|
||||
|
||||
int available() override {
|
||||
return _reader.available(_target);
|
||||
}
|
||||
|
||||
int read() override {
|
||||
return _reader.read(_target);
|
||||
}
|
||||
|
||||
int peek() override {
|
||||
return _reader.peek(_target);
|
||||
}
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
size_t readBytes(char *buffer, size_t size) override {
|
||||
return _reader.readBytes(_target, buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
// --- Client ---
|
||||
|
||||
int connect(IPAddress ip, uint16_t port) override {
|
||||
return _connection.connect(_target, ip, port);
|
||||
}
|
||||
|
||||
int connect(const char *ip, uint16_t port) override {
|
||||
return _connection.connect(_target, ip, port);
|
||||
}
|
||||
|
||||
uint8_t connected() override {
|
||||
return _connection.connected(_target);
|
||||
}
|
||||
|
||||
void stop() override {
|
||||
_writer.implicitFlush(_target);
|
||||
_connection.stop(_target);
|
||||
}
|
||||
|
||||
operator bool() override {
|
||||
return _connection.operator_bool(_target);
|
||||
}
|
||||
|
||||
int read(uint8_t *buf, size_t size) override {
|
||||
return _reader.read(_target, buf, size);
|
||||
}
|
||||
|
||||
void flush() override {
|
||||
_writer.flush(_target);
|
||||
}
|
||||
|
||||
protected:
|
||||
Client &_target;
|
||||
ReadPolicy _reader;
|
||||
WritePolicy _writer;
|
||||
ConnectPolicy _connection;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,23 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/HammingDecodingPolicy.hpp"
|
||||
#include "../Policies/HammingEncodingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingClient = ClientProxy<HammingDecodingPolicy<N, K, TAllocator>,
|
||||
HammingEncodingPolicy<N, K, TAllocator>,
|
||||
ConnectForwardingPolicy>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingClient = BasicHammingClient<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,24 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/HammingDecodingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingDecodingClient =
|
||||
ClientProxy<HammingDecodingPolicy<N, K, TAllocator>, WriteForwardingPolicy,
|
||||
ConnectForwardingPolicy>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingDecodingClient =
|
||||
BasicHammingDecodingClient<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,24 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/HammingEncodingPolicy.hpp"
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingEncodingClient =
|
||||
ClientProxy<ReadForwardingPolicy, HammingEncodingPolicy<N, K, TAllocator>,
|
||||
ConnectForwardingPolicy>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingEncodingClient =
|
||||
BasicHammingEncodingClient<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,23 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadLoggingPolicy.hpp"
|
||||
#include "../Policies/WriteLoggingPolicy.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct LoggingClient : ClientProxy<ReadLoggingPolicy, WriteLoggingPolicy,
|
||||
ConnectForwardingPolicy> {
|
||||
LoggingClient(Client &target, Print &log)
|
||||
: ClientProxy<ReadLoggingPolicy, WriteLoggingPolicy,
|
||||
ConnectForwardingPolicy>(target, ReadLoggingPolicy{log},
|
||||
WriteLoggingPolicy{log},
|
||||
ConnectForwardingPolicy{}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,92 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
#include "../Buffers/CircularBuffer.hpp"
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "../Streams/MemoryStream.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicMemoryClient : public Client {
|
||||
public:
|
||||
BasicMemoryClient(size_t capacity, TAllocator allocator = TAllocator())
|
||||
: _stream(capacity, allocator), _connected(false) {}
|
||||
|
||||
BasicMemoryClient(const BasicMemoryClient &src) : _stream(src._stream) {}
|
||||
|
||||
// --- Print ---
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
return _stream.write(data);
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *data, size_t size) override {
|
||||
return _stream.write(data, size);
|
||||
}
|
||||
|
||||
// --- Stream ---
|
||||
|
||||
int available() override {
|
||||
return _stream.available();
|
||||
}
|
||||
|
||||
int peek() override {
|
||||
return _stream.peek();
|
||||
}
|
||||
|
||||
int read() override {
|
||||
return _stream.read();
|
||||
}
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
size_t readBytes(char *data, size_t size) override {
|
||||
return _stream.readBytes(data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
void flush() override {
|
||||
_stream.flush();
|
||||
}
|
||||
|
||||
// --- Client ---
|
||||
|
||||
int connect(IPAddress, uint16_t) override {
|
||||
_connected = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int connect(const char *, uint16_t) override {
|
||||
_connected = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t connected() override {
|
||||
return _connected;
|
||||
}
|
||||
|
||||
void stop() override {
|
||||
_connected = false;
|
||||
}
|
||||
|
||||
operator bool() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
int read(uint8_t *buf, size_t size) override {
|
||||
return _stream.readBytes(reinterpret_cast<char *>(buf), size);
|
||||
}
|
||||
|
||||
private:
|
||||
BasicMemoryStream<TAllocator> _stream;
|
||||
bool _connected;
|
||||
};
|
||||
using MemoryClient = BasicMemoryClient<DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadBufferingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicReadBufferingClient
|
||||
: public ClientProxy<ReadBufferingPolicy<TAllocator>, WriteForwardingPolicy,
|
||||
ConnectForwardingPolicy> {
|
||||
using base_type = ClientProxy<ReadBufferingPolicy<TAllocator>,
|
||||
WriteForwardingPolicy, ConnectForwardingPolicy>;
|
||||
|
||||
public:
|
||||
explicit BasicReadBufferingClient(Client &target, size_t capacity,
|
||||
TAllocator allocator = TAllocator())
|
||||
: base_type(target, ReadBufferingPolicy<TAllocator>{capacity, allocator},
|
||||
WriteForwardingPolicy{}, ConnectForwardingPolicy{}) {}
|
||||
};
|
||||
|
||||
using ReadBufferingClient = BasicReadBufferingClient<DefaultAllocator>;
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,23 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadLoggingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct ReadLoggingClient : ClientProxy<ReadLoggingPolicy, WriteForwardingPolicy,
|
||||
ConnectForwardingPolicy> {
|
||||
ReadLoggingClient(Client &target, Print &log)
|
||||
: ClientProxy<ReadLoggingPolicy, WriteForwardingPolicy,
|
||||
ConnectForwardingPolicy>(target, ReadLoggingPolicy{log},
|
||||
WriteForwardingPolicy{},
|
||||
ConnectForwardingPolicy{}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,21 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectSpyingPolicy.hpp"
|
||||
#include "../Policies/ReadSpyingPolicy.hpp"
|
||||
#include "../Policies/WriteSpyingPolicy.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct SpyingClient
|
||||
: ClientProxy<ReadSpyingPolicy, WriteSpyingPolicy, ConnectSpyingPolicy> {
|
||||
SpyingClient(Client &target, Print &log)
|
||||
: ClientProxy<ReadSpyingPolicy, WriteSpyingPolicy, ConnectSpyingPolicy>(
|
||||
target, {log}, {log}, {log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,29 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteBufferingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
struct BasicWriteBufferingClient
|
||||
: ClientProxy<ReadForwardingPolicy, WriteBufferingPolicy<TAllocator>,
|
||||
ConnectForwardingPolicy> {
|
||||
explicit BasicWriteBufferingClient(Client &target, size_t capacity,
|
||||
TAllocator allocator = TAllocator())
|
||||
: ClientProxy<ReadForwardingPolicy, WriteBufferingPolicy<TAllocator>,
|
||||
ConnectForwardingPolicy>(
|
||||
target, ReadForwardingPolicy{},
|
||||
WriteBufferingPolicy<TAllocator>{capacity, allocator},
|
||||
ConnectForwardingPolicy{}) {}
|
||||
};
|
||||
|
||||
using WriteBufferingClient = BasicWriteBufferingClient<DefaultAllocator>;
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,24 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteLoggingPolicy.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteLoggingClient
|
||||
: ClientProxy<ReadForwardingPolicy, WriteLoggingPolicy,
|
||||
ConnectForwardingPolicy> {
|
||||
WriteLoggingClient(Client &target, Print &log)
|
||||
: ClientProxy<ReadForwardingPolicy, WriteLoggingPolicy,
|
||||
ConnectForwardingPolicy>(target, ReadForwardingPolicy{},
|
||||
WriteLoggingPolicy{log},
|
||||
ConnectForwardingPolicy{}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,30 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ConnectForwardingPolicy.hpp"
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteWaitingPolicy.hpp"
|
||||
#include "ClientProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteWaitingClient
|
||||
: ClientProxy<ReadForwardingPolicy, WriteWaitingPolicy,
|
||||
ConnectForwardingPolicy> {
|
||||
WriteWaitingClient(Client &target, Polyfills::function wait = yield)
|
||||
: ClientProxy<ReadForwardingPolicy, WriteWaitingPolicy,
|
||||
ConnectForwardingPolicy>(
|
||||
target, ReadForwardingPolicy{},
|
||||
WriteWaitingPolicy{Polyfills::move(wait)},
|
||||
ConnectForwardingPolicy{}) {}
|
||||
|
||||
void setTimeout(unsigned long timeout) {
|
||||
Client::setTimeout(timeout);
|
||||
_writer.setTimeout(timeout);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
53
lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp
Normal file
53
lib/ArduinoStreamUtils/src/StreamUtils/Configuration.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) || \
|
||||
defined(ARDUINO_ARCH_AVR)
|
||||
#define STREAMUTILS_PRINT_FLUSH_EXISTS 1
|
||||
#else
|
||||
#define STREAMUTILS_PRINT_FLUSH_EXISTS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || \
|
||||
defined(ARDUINO_ARCH_STM32)
|
||||
#define STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL 1
|
||||
#else
|
||||
#define STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STREAMUTILS_ENABLE_EEPROM
|
||||
#if defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_ESP8266) || \
|
||||
defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_STM32) || \
|
||||
defined(CORE_TEENSY)
|
||||
#define STREAMUTILS_ENABLE_EEPROM 1
|
||||
#else
|
||||
#define STREAMUTILS_ENABLE_EEPROM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STREAMUTILS_USE_EEPROM_COMMIT
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
#define STREAMUTILS_USE_EEPROM_COMMIT 1
|
||||
#else
|
||||
#define STREAMUTILS_USE_EEPROM_COMMIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STREAMUTILS_USE_EEPROM_UPDATE
|
||||
#if defined(ARDUINO_ARCH_AVR) || defined(CORE_TEENSY)
|
||||
#define STREAMUTILS_USE_EEPROM_UPDATE 1
|
||||
#else
|
||||
#define STREAMUTILS_USE_EEPROM_UPDATE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef STREAMUTILS_STACK_BUFFER_MAX_SIZE
|
||||
#define STREAMUTILS_STACK_BUFFER_MAX_SIZE 32
|
||||
#endif
|
||||
17
lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp
Normal file
17
lib/ArduinoStreamUtils/src/StreamUtils/Helpers.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
inline size_t readOrReadBytes(Stream &stream, char *buffer, size_t size) {
|
||||
return stream.readBytes(buffer, size);
|
||||
}
|
||||
|
||||
inline size_t readOrReadBytes(Client &client, char *buffer, size_t size) {
|
||||
return client.read(reinterpret_cast<uint8_t *>(buffer), size);
|
||||
}
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,35 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct ConnectForwardingPolicy {
|
||||
int connect(Client& target, const IPAddress& ip, uint16_t port) {
|
||||
return target.connect(ip, port);
|
||||
}
|
||||
|
||||
int connect(Client& target, const char* ip, uint16_t port) {
|
||||
return target.connect(ip, port);
|
||||
}
|
||||
|
||||
uint8_t connected(Client& target) {
|
||||
return target.connected();
|
||||
}
|
||||
|
||||
void stop(Client& target) {
|
||||
target.stop();
|
||||
}
|
||||
|
||||
bool operator_bool(Client& target) {
|
||||
return target.operator bool();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,68 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class ConnectSpyingPolicy {
|
||||
public:
|
||||
ConnectSpyingPolicy(Print& log) : _log(log) {}
|
||||
|
||||
int connect(Client& target, const IPAddress& ip, uint16_t port) {
|
||||
_log.print("connect('");
|
||||
_log.print(ip);
|
||||
_log.print("', ");
|
||||
_log.print(port);
|
||||
_log.print(") -> ");
|
||||
|
||||
int result = target.connect(ip, port);
|
||||
_log.println(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int connect(Client& target, const char* ip, uint16_t port) {
|
||||
_log.print("connect('");
|
||||
_log.print(ip);
|
||||
_log.print("', ");
|
||||
_log.print(port);
|
||||
_log.print(") -> ");
|
||||
|
||||
int result = target.connect(ip, port);
|
||||
_log.println(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t connected(Client& target) {
|
||||
_log.print("connected() -> ");
|
||||
|
||||
uint8_t result = target.connected();
|
||||
_log.println(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void stop(Client& target) {
|
||||
_log.print("stop()");
|
||||
target.stop();
|
||||
}
|
||||
|
||||
bool operator_bool(Client& target) {
|
||||
_log.print("operator bool() -> ");
|
||||
|
||||
bool result = target.operator bool();
|
||||
_log.println(result ? "true" : "false");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Print& _log;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,137 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <Client.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Helpers.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
class HammingDecodingPolicy;
|
||||
|
||||
template <typename TAllocator>
|
||||
class HammingDecodingPolicy<7, 4, TAllocator> {
|
||||
const static size_t sizeAllowedOnStack = STREAMUTILS_STACK_BUFFER_MAX_SIZE;
|
||||
|
||||
public:
|
||||
HammingDecodingPolicy(TAllocator allocator = TAllocator())
|
||||
: _allocator(allocator) {}
|
||||
|
||||
int available(Stream &stream) {
|
||||
int n = stream.available();
|
||||
if (_remainder >= 0)
|
||||
n++;
|
||||
return n / 2;
|
||||
}
|
||||
|
||||
template <typename TTarget> // Stream or Client
|
||||
int read(TTarget &target) {
|
||||
if (_remainder < 0) {
|
||||
_remainder = target.read();
|
||||
if (_remainder < 0)
|
||||
return -1;
|
||||
}
|
||||
int c = target.read();
|
||||
if (c < 0)
|
||||
return -1;
|
||||
int result = decode(_remainder, c);
|
||||
_remainder = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
int peek(Stream &stream) {
|
||||
if (_remainder < 0) {
|
||||
_remainder = stream.read();
|
||||
if (_remainder < 0)
|
||||
return -1;
|
||||
}
|
||||
int c = stream.peek();
|
||||
if (c < 0)
|
||||
return -1;
|
||||
return decode(_remainder, c);
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &stream, char *buffer, size_t size) {
|
||||
return doReadBytes(stream, buffer, size);
|
||||
}
|
||||
|
||||
int read(Client &client, uint8_t *buffer, size_t size) {
|
||||
return doReadBytes(client, reinterpret_cast<char *>(buffer), size);
|
||||
}
|
||||
|
||||
private:
|
||||
// Decode 7-bits to 4-bits using Hamming(7,4)
|
||||
uint8_t decode(uint8_t input) {
|
||||
// table is packed: each element contains two 4-bits values
|
||||
static uint8_t table[] = {
|
||||
0x00, 0x03, 0x05, 0xE7, 0x09, 0xEB, 0xED, 0xEE, 0x03, 0x33, 0x4D,
|
||||
0x63, 0x8D, 0xA3, 0xDD, 0xED, 0x05, 0x2B, 0x55, 0x65, 0x8B, 0xBB,
|
||||
0xC5, 0xEB, 0x81, 0x63, 0x65, 0x66, 0x88, 0x8B, 0x8D, 0x6F, 0x09,
|
||||
0x27, 0x47, 0x77, 0x99, 0xA9, 0xC9, 0xE7, 0x41, 0xA3, 0x44, 0x47,
|
||||
0xA9, 0xAA, 0x4D, 0xAF, 0x21, 0x22, 0xC5, 0x27, 0xC9, 0x2B, 0xCC,
|
||||
0xCF, 0x11, 0x21, 0x41, 0x6F, 0x81, 0xAF, 0xCF, 0xFF};
|
||||
uint8_t elem = table[input / 2];
|
||||
if (input % 2)
|
||||
return elem & 0x0f;
|
||||
|
||||
else
|
||||
return elem >> 4;
|
||||
}
|
||||
|
||||
uint8_t decode(uint8_t first, uint8_t second) {
|
||||
return decode(first) << 4 | decode(second);
|
||||
}
|
||||
|
||||
template <typename TTarget> // Stream or Client
|
||||
size_t doReadBytes(TTarget &target, char *output, size_t outputSize) {
|
||||
char *buffer;
|
||||
size_t bufferSize = outputSize * 2;
|
||||
|
||||
if (bufferSize > sizeAllowedOnStack) {
|
||||
buffer = static_cast<char *>(_allocator.allocate(bufferSize));
|
||||
if (!buffer) {
|
||||
// allocation failed => use the input buffer
|
||||
bufferSize = outputSize;
|
||||
buffer = output;
|
||||
}
|
||||
} else {
|
||||
buffer = static_cast<char *>(alloca(bufferSize));
|
||||
}
|
||||
|
||||
size_t loadedSize = 0;
|
||||
if (_remainder >= 0)
|
||||
buffer[loadedSize++] = _remainder;
|
||||
|
||||
loadedSize +=
|
||||
readOrReadBytes(target, buffer + loadedSize, bufferSize - loadedSize);
|
||||
for (size_t i = 0; i < loadedSize / 2; i++)
|
||||
output[i] = decode(buffer[2 * i], buffer[2 * i + 1]);
|
||||
|
||||
if (loadedSize % 2)
|
||||
_remainder = buffer[loadedSize - 1];
|
||||
else
|
||||
_remainder = -1;
|
||||
|
||||
if (bufferSize > sizeAllowedOnStack)
|
||||
_allocator.deallocate(buffer);
|
||||
|
||||
return loadedSize / 2;
|
||||
}
|
||||
|
||||
TAllocator _allocator;
|
||||
char _remainder = -1;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,116 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
|
||||
#include <malloc.h>
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
class HammingEncodingPolicy;
|
||||
|
||||
template <typename TAllocator>
|
||||
class HammingEncodingPolicy<7, 4, TAllocator> {
|
||||
const static size_t sizeAllowedOnStack = STREAMUTILS_STACK_BUFFER_MAX_SIZE;
|
||||
|
||||
public:
|
||||
HammingEncodingPolicy(TAllocator allocator = TAllocator())
|
||||
: _allocator(allocator) {}
|
||||
|
||||
size_t write(Print &target, const uint8_t *data, size_t size) {
|
||||
if (!flushRemainder(target))
|
||||
return 0;
|
||||
|
||||
size_t bufferSize = size * 2;
|
||||
uint8_t *buffer;
|
||||
if (bufferSize > sizeAllowedOnStack) {
|
||||
buffer = static_cast<uint8_t *>(_allocator.allocate(bufferSize));
|
||||
if (!buffer) {
|
||||
bufferSize = sizeAllowedOnStack;
|
||||
buffer = static_cast<uint8_t *>(alloca(bufferSize));
|
||||
}
|
||||
} else {
|
||||
buffer = static_cast<uint8_t *>(alloca(bufferSize));
|
||||
}
|
||||
|
||||
for (size_t i = 0, j = 0; j < bufferSize; i++) {
|
||||
buffer[j++] = encode(data[i] >> 4);
|
||||
buffer[j++] = encode(data[i] & 0x0f);
|
||||
}
|
||||
size_t n = target.write(buffer, bufferSize);
|
||||
if (n & 1) {
|
||||
_remainder = buffer[n];
|
||||
++n;
|
||||
}
|
||||
|
||||
if (bufferSize > sizeAllowedOnStack)
|
||||
_allocator.deallocate(buffer);
|
||||
|
||||
return n / 2;
|
||||
}
|
||||
|
||||
size_t write(Print &target, uint8_t data) {
|
||||
uint8_t first = encode(data >> 4);
|
||||
uint8_t second = encode(data & 0x0f);
|
||||
|
||||
if (!flushRemainder(target))
|
||||
return 0;
|
||||
|
||||
if (!target.write(first))
|
||||
return 0;
|
||||
|
||||
if (!target.write(second))
|
||||
_remainder = second;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void flush(Stream &target) {
|
||||
flushRemainder(target);
|
||||
target.flush();
|
||||
}
|
||||
|
||||
void flush(Print &target) {
|
||||
flushRemainder(target);
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
target.flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
void implicitFlush(Print &target) {
|
||||
flushRemainder(target);
|
||||
}
|
||||
|
||||
private:
|
||||
// Encode 4-bits to 7-bits using Hamming(7,4)
|
||||
uint8_t encode(uint8_t input) {
|
||||
static uint8_t table[] = {0x00, 0x71, 0x62, 0x13, 0x54, 0x25, 0x36, 0x47,
|
||||
0x38, 0x49, 0x5A, 0x2B, 0x6C, 0x1D, 0x0E, 0x7F};
|
||||
return table[input];
|
||||
}
|
||||
|
||||
template <typename TTarget>
|
||||
bool flushRemainder(TTarget &target) {
|
||||
if (_remainder < 0)
|
||||
return true;
|
||||
|
||||
if (!target.write(_remainder))
|
||||
return false;
|
||||
|
||||
_remainder = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
TAllocator _allocator;
|
||||
int16_t _remainder = -1;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,97 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Buffers/LinearBuffer.hpp"
|
||||
#include "../Helpers.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
struct ReadBufferingPolicy {
|
||||
ReadBufferingPolicy(size_t capacity, TAllocator allocator = TAllocator())
|
||||
: _buffer(capacity, allocator) {}
|
||||
|
||||
ReadBufferingPolicy(const ReadBufferingPolicy &other)
|
||||
: _buffer(other._buffer) {}
|
||||
|
||||
int available(Stream &stream) {
|
||||
return stream.available() + _buffer.available();
|
||||
}
|
||||
|
||||
template <typename TTarget> // Stream or Client
|
||||
int read(TTarget &target) {
|
||||
if (!_buffer)
|
||||
return target.read();
|
||||
|
||||
if (_buffer.available() > 0)
|
||||
return _buffer.read();
|
||||
|
||||
size_t avail = static_cast<size_t>(target.available());
|
||||
if (avail <= 1)
|
||||
return target.read();
|
||||
|
||||
_buffer.reloadFrom(target, avail);
|
||||
return _buffer.read();
|
||||
}
|
||||
|
||||
int peek(Stream &stream) {
|
||||
return isEmpty() ? stream.peek() : _buffer.peek();
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &stream, char *buffer, size_t size) {
|
||||
return doReadBytes(stream, buffer, size);
|
||||
}
|
||||
|
||||
int read(Client &client, uint8_t *buffer, size_t size) {
|
||||
return doReadBytes(client, reinterpret_cast<char *>(buffer), size);
|
||||
}
|
||||
|
||||
private:
|
||||
bool isEmpty() const {
|
||||
return _buffer.available() == 0;
|
||||
}
|
||||
|
||||
LinearBuffer<TAllocator> _buffer;
|
||||
|
||||
template <typename TTarget> // Stream or Client
|
||||
size_t doReadBytes(TTarget &target, char *buffer, size_t size) {
|
||||
if (!_buffer)
|
||||
return readOrReadBytes(target, buffer, size);
|
||||
|
||||
size_t result = 0;
|
||||
|
||||
// can we read from buffer?
|
||||
if (_buffer.available() > 0) {
|
||||
size_t bytesRead = _buffer.readBytes(buffer, size);
|
||||
result += bytesRead;
|
||||
buffer += bytesRead;
|
||||
size -= bytesRead;
|
||||
}
|
||||
|
||||
// still something to read?
|
||||
if (size > 0) {
|
||||
// (at this point, the buffer is empty)
|
||||
|
||||
size_t avail = static_cast<size_t>(target.available());
|
||||
|
||||
// should we use the buffer?
|
||||
if (avail > size && size < _buffer.capacity()) {
|
||||
_buffer.reloadFrom(target, avail);
|
||||
size_t bytesRead = _buffer.readBytes(buffer, size);
|
||||
result += bytesRead;
|
||||
} else {
|
||||
// we can bypass the buffer
|
||||
result += readOrReadBytes(target, buffer, size);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}; // namespace StreamUtils
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,33 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct ReadForwardingPolicy {
|
||||
int available(Stream &target) {
|
||||
return target.available();
|
||||
}
|
||||
|
||||
int read(Stream &target) {
|
||||
return target.read();
|
||||
}
|
||||
|
||||
int peek(Stream &target) {
|
||||
return target.peek();
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &target, char *buffer, size_t size) {
|
||||
return target.readBytes(buffer, size);
|
||||
}
|
||||
|
||||
int read(Client &target, uint8_t *buffer, size_t size) {
|
||||
return target.read(buffer, size);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,46 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class ReadLoggingPolicy {
|
||||
public:
|
||||
ReadLoggingPolicy(Print &log) : _log(log) {}
|
||||
|
||||
int available(Stream &stream) {
|
||||
return stream.available();
|
||||
}
|
||||
|
||||
int read(Stream &stream) {
|
||||
int result = stream.read();
|
||||
if (result >= 0)
|
||||
_log.write(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int peek(Stream &stream) {
|
||||
return stream.peek();
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &stream, char *buffer, size_t size) {
|
||||
size_t result = stream.readBytes(buffer, size);
|
||||
_log.write(buffer, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int read(Client &client, uint8_t *buffer, size_t size) {
|
||||
int result = client.read(buffer, size);
|
||||
_log.write(buffer, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Print &_log;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,64 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class ReadSpyingPolicy {
|
||||
public:
|
||||
ReadSpyingPolicy(Print &log) : _log(log) {}
|
||||
|
||||
int available(Stream &target) {
|
||||
int result = target.available();
|
||||
_log.print("available() -> ");
|
||||
_log.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int read(Stream &target) {
|
||||
int result = target.read();
|
||||
_log.print("read() -> ");
|
||||
_log.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
int peek(Stream &target) {
|
||||
int result = target.peek();
|
||||
_log.print("peek() -> ");
|
||||
_log.println(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &target, char *buffer, size_t size) {
|
||||
size_t result = target.readBytes(buffer, size);
|
||||
_log.print("readBytes(");
|
||||
_log.print(size);
|
||||
_log.print(") -> ");
|
||||
_log.print(result);
|
||||
if (size > result)
|
||||
_log.print(" [timeout]");
|
||||
_log.println();
|
||||
return result;
|
||||
}
|
||||
|
||||
int read(Client &target, uint8_t *buffer, size_t size) {
|
||||
int result = target.read(buffer, size);
|
||||
_log.print("read(");
|
||||
_log.print(size);
|
||||
_log.print(") -> ");
|
||||
_log.print(result);
|
||||
if (static_cast<int>(size) > result)
|
||||
_log.print(" [timeout]");
|
||||
_log.println();
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Print &_log;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,47 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TThrottler>
|
||||
struct ReadThrottlingPolicy {
|
||||
ReadThrottlingPolicy(TThrottler throttler) : _throttler(throttler) {}
|
||||
|
||||
int available(Stream &stream) {
|
||||
return stream.available();
|
||||
}
|
||||
|
||||
int read(Stream &stream) {
|
||||
_throttler.throttle();
|
||||
return stream.read();
|
||||
}
|
||||
|
||||
int peek(Stream &stream) {
|
||||
_throttler.throttle();
|
||||
return stream.peek();
|
||||
}
|
||||
|
||||
size_t readBytes(Stream &stream, char *buffer, size_t size) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
int c = read(stream);
|
||||
if (c < 0)
|
||||
return i;
|
||||
buffer[i] = c;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
const TThrottler &throttler() const {
|
||||
return _throttler;
|
||||
}
|
||||
|
||||
private:
|
||||
TThrottler _throttler;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,78 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Buffers/LinearBuffer.hpp"
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
struct WriteBufferingPolicy {
|
||||
public:
|
||||
WriteBufferingPolicy(size_t capacity, TAllocator allocator)
|
||||
: _buffer(capacity, allocator) {}
|
||||
|
||||
size_t write(Print &target, const uint8_t *data, size_t size) {
|
||||
size_t result = 0;
|
||||
|
||||
// continue to fill the buffer?
|
||||
if (!_buffer.isEmpty()) {
|
||||
size_t n = _buffer.write(data, size);
|
||||
data += n;
|
||||
size -= n;
|
||||
result += n;
|
||||
|
||||
// time to flush?
|
||||
if (_buffer.isFull()) {
|
||||
_buffer.flushInto(target);
|
||||
}
|
||||
}
|
||||
|
||||
// something left to write?
|
||||
if (size > 0) {
|
||||
// can we bypass the buffer?
|
||||
if (size >= _buffer.capacity()) {
|
||||
result += target.write(data, size);
|
||||
} else {
|
||||
result += _buffer.write(data, size);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t write(Print &target, uint8_t data) {
|
||||
if (!_buffer)
|
||||
return target.write(data);
|
||||
|
||||
_buffer.write(data);
|
||||
if (_buffer.isFull())
|
||||
_buffer.flushInto(target);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void flush(Stream &target) {
|
||||
_buffer.flushInto(target);
|
||||
target.flush();
|
||||
}
|
||||
|
||||
void flush(Print &target) {
|
||||
_buffer.flushInto(target);
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
target.flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
void implicitFlush(Print &target) {
|
||||
_buffer.flushInto(target);
|
||||
}
|
||||
|
||||
private:
|
||||
LinearBuffer<TAllocator> _buffer;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,27 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteForwardingPolicy {
|
||||
template <typename... Args>
|
||||
size_t write(Stream &stream, Args... args) {
|
||||
return stream.write(args...);
|
||||
}
|
||||
|
||||
void flush(Stream &stream) {
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
void implicitFlush(Stream &) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,39 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Client.h>
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class WriteLoggingPolicy {
|
||||
public:
|
||||
WriteLoggingPolicy(Print &log) : _log(log) {}
|
||||
|
||||
size_t write(Print &target, const uint8_t *buffer, size_t size) {
|
||||
size_t result = target.write(buffer, size);
|
||||
_log.write(buffer, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t write(Print &target, uint8_t c) {
|
||||
size_t result = target.write(c);
|
||||
_log.write(c);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TTarget>
|
||||
void flush(TTarget &target) {
|
||||
target.flush();
|
||||
}
|
||||
|
||||
void implicitFlush(Print &) {}
|
||||
|
||||
private:
|
||||
Print &_log;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,55 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class WriteSpyingPolicy {
|
||||
public:
|
||||
WriteSpyingPolicy(Print &log) : _log(log) {}
|
||||
|
||||
size_t write(Print &stream, const uint8_t *buffer, size_t size) {
|
||||
_log.print("write('");
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
_log.write(buffer[i]);
|
||||
}
|
||||
_log.print("', ");
|
||||
_log.print(size);
|
||||
_log.print(") -> ");
|
||||
|
||||
size_t result = stream.write(buffer, size);
|
||||
_log.println(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t write(Print &stream, uint8_t data) {
|
||||
_log.print("write('");
|
||||
_log.write(data);
|
||||
_log.print("') -> ");
|
||||
|
||||
size_t result = stream.write(data);
|
||||
_log.println(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TTarget>
|
||||
void flush(TTarget &target) {
|
||||
_log.println("flush()");
|
||||
target.flush();
|
||||
}
|
||||
|
||||
void implicitFlush(Print &) {}
|
||||
|
||||
private:
|
||||
Print &_log;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,63 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "../Buffers/LinearBuffer.hpp"
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteWaitingPolicy {
|
||||
public:
|
||||
WriteWaitingPolicy(Polyfills::function wait)
|
||||
: _wait(Polyfills::move(wait)), _timeout(1000) {}
|
||||
|
||||
size_t write(Print &target, const uint8_t *data, size_t size) {
|
||||
unsigned long startTime = millis();
|
||||
size_t totalWritten = 0;
|
||||
|
||||
for (;;) {
|
||||
size_t n = target.write(data, size);
|
||||
size -= n;
|
||||
data += n;
|
||||
totalWritten += n;
|
||||
if (size == 0 || millis() - startTime >= _timeout)
|
||||
return totalWritten;
|
||||
_wait();
|
||||
}
|
||||
}
|
||||
|
||||
size_t write(Print &target, uint8_t data) {
|
||||
unsigned long startTime = millis();
|
||||
|
||||
for (;;) {
|
||||
if (target.write(data))
|
||||
return 1;
|
||||
if (millis() - startTime >= _timeout)
|
||||
return 0;
|
||||
_wait();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TTarget>
|
||||
void flush(TTarget &target) {
|
||||
target.flush();
|
||||
}
|
||||
|
||||
void implicitFlush(Print &) {}
|
||||
|
||||
void setTimeout(unsigned long timeout) {
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
private:
|
||||
Polyfills::function _wait;
|
||||
unsigned long _timeout;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
60
lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp
Normal file
60
lib/ArduinoStreamUtils/src/StreamUtils/Polyfills.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace StreamUtils {
|
||||
namespace Polyfills {
|
||||
|
||||
template <typename T>
|
||||
struct remove_reference {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct remove_reference<T &> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
typename remove_reference<T>::type &&move(T &&t) {
|
||||
return static_cast<typename remove_reference<T>::type &&>(t);
|
||||
}
|
||||
|
||||
// poor man's std::function<void()>
|
||||
class function {
|
||||
struct callable_base {
|
||||
virtual void operator()() = 0;
|
||||
virtual ~callable_base() {}
|
||||
};
|
||||
|
||||
template <typename Functor>
|
||||
struct callable : callable_base {
|
||||
Functor functor;
|
||||
callable(Functor functor) : functor(functor) {}
|
||||
virtual void operator()() {
|
||||
functor();
|
||||
}
|
||||
};
|
||||
|
||||
callable_base *_callable;
|
||||
|
||||
public:
|
||||
template <typename Functor>
|
||||
function(Functor f) {
|
||||
_callable = new callable<Functor>(f);
|
||||
}
|
||||
function(function &&src) {
|
||||
_callable = src._callable, src._callable = 0;
|
||||
}
|
||||
~function() {
|
||||
delete _callable;
|
||||
}
|
||||
void operator()() const {
|
||||
(*_callable)();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Polyfills
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,29 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class ArduinoThrottler {
|
||||
public:
|
||||
ArduinoThrottler(uint32_t rate) : _interval(1000000 / rate), _last(0) {}
|
||||
|
||||
void throttle() {
|
||||
auto now = micros();
|
||||
auto elapsed = now - _last;
|
||||
|
||||
if (elapsed < _interval) {
|
||||
delayMicroseconds(_interval - elapsed);
|
||||
}
|
||||
|
||||
_last = now;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned long _interval;
|
||||
unsigned long _last;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,21 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
#include <stdlib.h> // malloc, free, size_t
|
||||
|
||||
struct DefaultAllocator {
|
||||
void* allocate(size_t n) {
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
void deallocate(void* p) {
|
||||
free(p);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,22 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/WriteBufferingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "PrintProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
struct BasicBufferingPrint : PrintProxy<WriteBufferingPolicy<TAllocator>> {
|
||||
explicit BasicBufferingPrint(Print &upstream, size_t capacity,
|
||||
TAllocator allocator = TAllocator())
|
||||
: PrintProxy<WriteBufferingPolicy<TAllocator>>(upstream,
|
||||
{capacity, allocator}) {}
|
||||
};
|
||||
|
||||
using BufferingPrint = BasicBufferingPrint<DefaultAllocator>;
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,19 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/HammingEncodingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "PrintProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingPrint = PrintProxy<HammingEncodingPolicy<N, K, TAllocator>>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingPrint = BasicHammingPrint<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,17 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/WriteLoggingPolicy.hpp"
|
||||
#include "PrintProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct LoggingPrint : PrintProxy<WriteLoggingPolicy> {
|
||||
LoggingPrint(Print &upstream, Print &log)
|
||||
: PrintProxy<WriteLoggingPolicy>(upstream, {log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
50
lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp
Normal file
50
lib/ArduinoStreamUtils/src/StreamUtils/Prints/PrintProxy.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename WritePolicy>
|
||||
class PrintProxy : public Print {
|
||||
public:
|
||||
explicit PrintProxy(Print &upstream, WritePolicy writer = WritePolicy{})
|
||||
: _target(upstream), _writer(Polyfills::move(writer)) {}
|
||||
|
||||
PrintProxy(const PrintProxy &other)
|
||||
: _target(other._target), _writer(other._writer) {}
|
||||
|
||||
~PrintProxy() {
|
||||
_writer.implicitFlush(_target);
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size) override {
|
||||
return _writer.write(_target, buffer, size);
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
return _writer.write(_target, data);
|
||||
}
|
||||
|
||||
#if STREAMUTILS_PRINT_FLUSH_EXISTS
|
||||
void flush() override {
|
||||
#else
|
||||
void flush() {
|
||||
#endif
|
||||
_writer.flush(_target);
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
|
||||
protected:
|
||||
Print &_target;
|
||||
WritePolicy _writer;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,17 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/WriteSpyingPolicy.hpp"
|
||||
#include "PrintProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct SpyingPrint : PrintProxy<WriteSpyingPolicy> {
|
||||
SpyingPrint(Print &target, Print &log)
|
||||
: PrintProxy<WriteSpyingPolicy>(target, WriteSpyingPolicy{log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,52 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Print.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include "../Polyfills.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class StringPrint : public Print {
|
||||
public:
|
||||
StringPrint() {}
|
||||
|
||||
explicit StringPrint(String str) : _str(Polyfills::move(str)) {}
|
||||
|
||||
size_t write(const uint8_t* p, size_t n) override {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
uint8_t c = p[i];
|
||||
if (c == 0)
|
||||
return i;
|
||||
write(c);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t write(uint8_t c) override {
|
||||
if (c == 0)
|
||||
return 0;
|
||||
_str += static_cast<char>(c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const String& str() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
void str(String str) {
|
||||
_str = Polyfills::move(str);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_str = "";
|
||||
}
|
||||
|
||||
private:
|
||||
String _str;
|
||||
};
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,22 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/WriteWaitingPolicy.hpp"
|
||||
#include "PrintProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WaitingPrint : PrintProxy<WriteWaitingPolicy> {
|
||||
WaitingPrint(Print &target, Polyfills::function wait = yield)
|
||||
: PrintProxy<WriteWaitingPolicy>(
|
||||
target, WriteWaitingPolicy{Polyfills::move(wait)}) {}
|
||||
|
||||
void setTimeout(unsigned long timeout) {
|
||||
_writer.setTimeout(timeout);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,76 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
#if STREAMUTILS_ENABLE_EEPROM
|
||||
|
||||
#include <EEPROM.h>
|
||||
#include <Stream.h>
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class EepromStream : public Stream {
|
||||
public:
|
||||
EepromStream(size_t address, size_t size)
|
||||
: _readAddress(address), _writeAddress(address), _end(address + size) {}
|
||||
|
||||
int available() override {
|
||||
return _end - _readAddress;
|
||||
}
|
||||
|
||||
int read() override {
|
||||
if (_readAddress >= _end)
|
||||
return -1;
|
||||
return EEPROM.read(_readAddress++);
|
||||
}
|
||||
|
||||
int peek() override {
|
||||
if (_readAddress >= _end)
|
||||
return -1;
|
||||
return EEPROM.read(_readAddress);
|
||||
}
|
||||
|
||||
void flush() override {
|
||||
#if STREAMUTILS_USE_EEPROM_COMMIT
|
||||
EEPROM.commit();
|
||||
#endif
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size) override {
|
||||
size_t remaining = _end - _writeAddress;
|
||||
if (size > remaining)
|
||||
size = remaining;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
#if STREAMUTILS_USE_EEPROM_UPDATE
|
||||
EEPROM.update(_writeAddress++, buffer[i]);
|
||||
#else
|
||||
EEPROM.write(_writeAddress++, buffer[i]);
|
||||
#endif
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
if (_writeAddress >= _end)
|
||||
return 0;
|
||||
#if STREAMUTILS_USE_EEPROM_UPDATE
|
||||
EEPROM.update(_writeAddress++, data);
|
||||
#else
|
||||
EEPROM.write(_writeAddress++, data);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t _readAddress, _writeAddress, _end;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/HammingDecodingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingDecodingStream =
|
||||
StreamProxy<HammingDecodingPolicy<N, K, TAllocator>, WriteForwardingPolicy>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingDecodingStream =
|
||||
BasicHammingDecodingStream<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,22 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/HammingEncodingPolicy.hpp"
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingEncodingStream =
|
||||
StreamProxy<ReadForwardingPolicy, HammingEncodingPolicy<N, K, TAllocator>>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingEncodingStream =
|
||||
BasicHammingEncodingStream<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,21 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/HammingDecodingPolicy.hpp"
|
||||
#include "../Policies/HammingEncodingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <int N, int K, typename TAllocator>
|
||||
using BasicHammingStream = StreamProxy<HammingDecodingPolicy<N, K, TAllocator>,
|
||||
HammingEncodingPolicy<N, K, TAllocator>>;
|
||||
|
||||
template <int N, int K>
|
||||
using HammingStream = BasicHammingStream<N, K, DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,19 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadLoggingPolicy.hpp"
|
||||
#include "../Policies/WriteLoggingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct LoggingStream : StreamProxy<ReadLoggingPolicy, WriteLoggingPolicy> {
|
||||
LoggingStream(Stream& target, Print& log)
|
||||
: StreamProxy<ReadLoggingPolicy, WriteLoggingPolicy>(
|
||||
target, ReadLoggingPolicy{log}, WriteLoggingPolicy{log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,61 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
#include "../Buffers/CircularBuffer.hpp"
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicMemoryStream : public Stream {
|
||||
public:
|
||||
BasicMemoryStream(size_t capacity, TAllocator allocator = TAllocator())
|
||||
: _buffer(capacity, allocator) {}
|
||||
|
||||
BasicMemoryStream(const BasicMemoryStream &src) : _buffer(src._buffer) {}
|
||||
|
||||
int available() override {
|
||||
return static_cast<int>(_buffer.available());
|
||||
}
|
||||
|
||||
int peek() override {
|
||||
return _buffer.isEmpty() ? -1 : _buffer.peek();
|
||||
}
|
||||
|
||||
int read() override {
|
||||
return _buffer.isEmpty() ? -1 : _buffer.read();
|
||||
}
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
size_t readBytes(char *data, size_t size) override {
|
||||
return _buffer.readBytes(data, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
return _buffer.isFull() ? 0 : _buffer.write(data);
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *data, size_t size) override {
|
||||
return _buffer.write(data, size);
|
||||
}
|
||||
|
||||
using Stream::write;
|
||||
|
||||
void flush() override {
|
||||
_buffer.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
CircularBuffer<TAllocator> _buffer;
|
||||
};
|
||||
|
||||
using MemoryStream = BasicMemoryStream<DefaultAllocator>;
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,28 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadBufferingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicReadBufferingStream
|
||||
: public StreamProxy<ReadBufferingPolicy<TAllocator>,
|
||||
WriteForwardingPolicy> {
|
||||
using base_type =
|
||||
StreamProxy<ReadBufferingPolicy<TAllocator>, WriteForwardingPolicy>;
|
||||
|
||||
public:
|
||||
explicit BasicReadBufferingStream(Stream &upstream, size_t capacity,
|
||||
TAllocator allocator = TAllocator())
|
||||
: base_type(upstream, {capacity, allocator}, {}) {}
|
||||
};
|
||||
|
||||
using ReadBufferingStream = BasicReadBufferingStream<DefaultAllocator>;
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,19 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadLoggingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct ReadLoggingStream
|
||||
: StreamProxy<ReadLoggingPolicy, WriteForwardingPolicy> {
|
||||
ReadLoggingStream(Stream &target, Print &log)
|
||||
: StreamProxy<ReadLoggingPolicy, WriteForwardingPolicy>(
|
||||
target, ReadLoggingPolicy{log}, WriteForwardingPolicy{}) {}
|
||||
};
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,35 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadThrottlingPolicy.hpp"
|
||||
#include "../Policies/WriteForwardingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
#ifdef ARDUINO
|
||||
#include "../Ports/ArduinoThrottler.hpp"
|
||||
#endif
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TThrottler>
|
||||
class BasicReadThrottlingStream
|
||||
: public StreamProxy<ReadThrottlingPolicy<TThrottler>,
|
||||
WriteForwardingPolicy> {
|
||||
public:
|
||||
BasicReadThrottlingStream(Stream& upstream,
|
||||
TThrottler throttler = TThrottler())
|
||||
: StreamProxy<ReadThrottlingPolicy<TThrottler>, WriteForwardingPolicy>(
|
||||
upstream, ReadThrottlingPolicy<TThrottler>(throttler), {}) {}
|
||||
|
||||
const TThrottler& throttler() const {
|
||||
return this->_reader.throttler();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef ARDUINO
|
||||
using ReadThrottlingStream = BasicReadThrottlingStream<ArduinoThrottler>;
|
||||
#endif
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,19 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadSpyingPolicy.hpp"
|
||||
#include "../Policies/WriteSpyingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct SpyingStream : StreamProxy<ReadSpyingPolicy, WriteSpyingPolicy> {
|
||||
SpyingStream(Stream &target, Print &log)
|
||||
: StreamProxy<ReadSpyingPolicy, WriteSpyingPolicy>(
|
||||
target, ReadSpyingPolicy{log}, WriteSpyingPolicy{log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,68 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
#include "../Polyfills.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename ReadPolicy, typename WritePolicy>
|
||||
class StreamProxy : public Stream {
|
||||
public:
|
||||
explicit StreamProxy(Stream &upstream, ReadPolicy reader = ReadPolicy{},
|
||||
WritePolicy writer = WritePolicy{})
|
||||
: _upstream(upstream),
|
||||
_reader(reader),
|
||||
_writer(Polyfills::move(writer)) {}
|
||||
|
||||
StreamProxy(const StreamProxy &other)
|
||||
: _upstream(other._upstream),
|
||||
_reader(other._reader),
|
||||
_writer(other._writer) {}
|
||||
|
||||
~StreamProxy() {
|
||||
_writer.implicitFlush(_upstream);
|
||||
}
|
||||
|
||||
size_t write(const uint8_t *buffer, size_t size) override {
|
||||
return _writer.write(_upstream, buffer, size);
|
||||
}
|
||||
|
||||
size_t write(uint8_t data) override {
|
||||
return _writer.write(_upstream, data);
|
||||
}
|
||||
|
||||
using Stream::write;
|
||||
|
||||
int available() override {
|
||||
return _reader.available(_upstream);
|
||||
}
|
||||
|
||||
int read() override {
|
||||
return _reader.read(_upstream);
|
||||
}
|
||||
|
||||
int peek() override {
|
||||
return _reader.peek(_upstream);
|
||||
}
|
||||
|
||||
void flush() override {
|
||||
_writer.flush(_upstream);
|
||||
}
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
size_t readBytes(char *buffer, size_t size) override {
|
||||
return _reader.readBytes(_upstream, buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Stream &_upstream;
|
||||
ReadPolicy _reader;
|
||||
WritePolicy _writer;
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,77 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
#include <WString.h>
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
class StringStream : public Stream {
|
||||
public:
|
||||
StringStream() {}
|
||||
|
||||
explicit StringStream(String str) : _str(Polyfills::move(str)) {}
|
||||
|
||||
size_t write(const uint8_t* p, size_t n) override {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
uint8_t c = p[i];
|
||||
if (c == 0)
|
||||
return i;
|
||||
write(c);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t write(uint8_t c) override {
|
||||
if (c == 0)
|
||||
return 0;
|
||||
_str += static_cast<char>(c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const String& str() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
void str(String str) {
|
||||
_str = Polyfills::move(str);
|
||||
}
|
||||
|
||||
int available() override {
|
||||
return _str.length();
|
||||
}
|
||||
|
||||
int read() override {
|
||||
if (_str.length() == 0)
|
||||
return -1;
|
||||
char c = _str[0];
|
||||
_str.remove(0, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
#if STREAMUTILS_STREAM_READBYTES_IS_VIRTUAL
|
||||
size_t readBytes(char* buffer, size_t length) override {
|
||||
if (length > _str.length())
|
||||
length = _str.length();
|
||||
_str.toCharArray(buffer, length);
|
||||
_str.remove(0, length);
|
||||
return length;
|
||||
}
|
||||
#endif
|
||||
|
||||
int peek() override {
|
||||
return _str.length() > 0 ? _str[0] : -1;
|
||||
}
|
||||
|
||||
void flush() override {}
|
||||
|
||||
private:
|
||||
String _str;
|
||||
};
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,24 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteBufferingPolicy.hpp"
|
||||
#include "../Ports/DefaultAllocator.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
template <typename TAllocator>
|
||||
struct BasicWriteBufferingStream
|
||||
: StreamProxy<ReadForwardingPolicy, WriteBufferingPolicy<TAllocator>> {
|
||||
explicit BasicWriteBufferingStream(Stream &upstream, size_t capacity,
|
||||
TAllocator allocator = TAllocator())
|
||||
: StreamProxy<ReadForwardingPolicy, WriteBufferingPolicy<TAllocator>>(
|
||||
upstream, {}, {capacity, allocator}) {}
|
||||
};
|
||||
|
||||
using WriteBufferingStream = BasicWriteBufferingStream<DefaultAllocator>;
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,20 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteLoggingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteLoggingStream
|
||||
: StreamProxy<ReadForwardingPolicy, WriteLoggingPolicy> {
|
||||
WriteLoggingStream(Stream &target, Print &log)
|
||||
: StreamProxy<ReadForwardingPolicy, WriteLoggingPolicy>(
|
||||
target, ReadForwardingPolicy{}, WriteLoggingPolicy{log}) {}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
@@ -0,0 +1,26 @@
|
||||
// StreamUtils - github.com/bblanchon/ArduinoStreamUtils
|
||||
// Copyright Benoit Blanchon 2019-2021
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Policies/ReadForwardingPolicy.hpp"
|
||||
#include "../Policies/WriteWaitingPolicy.hpp"
|
||||
#include "StreamProxy.hpp"
|
||||
|
||||
namespace StreamUtils {
|
||||
|
||||
struct WriteWaitingStream
|
||||
: StreamProxy<ReadForwardingPolicy, WriteWaitingPolicy> {
|
||||
WriteWaitingStream(Stream &target, Polyfills::function wait = yield)
|
||||
: StreamProxy<ReadForwardingPolicy, WriteWaitingPolicy>(
|
||||
target, ReadForwardingPolicy{},
|
||||
WriteWaitingPolicy{Polyfills::move(wait)}) {}
|
||||
|
||||
void setTimeout(unsigned long timeout) {
|
||||
Stream::setTimeout(timeout);
|
||||
_writer.setTimeout(timeout);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace StreamUtils
|
||||
Reference in New Issue
Block a user