diff --git a/cores/esp8266/cbuf.cpp b/cores/esp8266/cbuf.cpp index 8f36cf8a2..cf539e6b0 100644 --- a/cores/esp8266/cbuf.cpp +++ b/cores/esp8266/cbuf.cpp @@ -21,6 +21,51 @@ #include "cbuf.h" #include "c_types.h" +cbuf::cbuf(size_t size) : + _size(size), _buf(new char[size]), _bufend(_buf + size), _begin(_buf), _end(_begin) { +} + +cbuf::~cbuf() { + delete[] _buf; +} + +size_t cbuf::resizeAdd(size_t addSize) { + return resize(_size + addSize); +} + +size_t cbuf::resize(size_t newSize) { + + size_t available = getSize(); + + // not lose any data + // if data can be lost use remove or flush before resize + if((newSize < available) || (newSize == _size)) { + return _size; + } + + char *newbuf = new char[newSize]; + char *oldbuf = _buf; + + if(!newbuf) { + return _size; + } + + if(_buf) { + read(newbuf, available); + memset((newbuf + available), 0x00, (newSize - available)); + } + + _begin = newbuf; + _end = newbuf + available; + _bufend = newbuf + newSize; + _size = newSize; + + _buf = newbuf; + delete[] oldbuf; + + return _size; +} + size_t ICACHE_RAM_ATTR cbuf::getSize() const { if(_end >= _begin) { return _end - _begin; @@ -28,18 +73,103 @@ size_t ICACHE_RAM_ATTR cbuf::getSize() const { return _size - (_begin - _end); } +size_t cbuf::room() const { + if(_end >= _begin) { + return _size - (_end - _begin) - 1; + } + return _begin - _end - 1; +} + +int cbuf::peek() { + if(empty()) + return -1; + + return static_cast(*_begin); +} + +size_t cbuf::peek(char *dst, size_t size) { + size_t bytes_available = getSize(); + size_t size_to_read = (size < bytes_available) ? size : bytes_available; + size_t size_read = size_to_read; + char * begin = _begin; + if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) { + size_t top_size = _bufend - _begin; + memcpy(dst, _begin, top_size); + begin = _buf; + size_to_read -= top_size; + dst += top_size; + } + memcpy(dst, begin, size_to_read); + return size_read; +} + int ICACHE_RAM_ATTR cbuf::read() { - if(empty()) return -1; + if(empty()) + return -1; char result = *_begin; _begin = wrap_if_bufend(_begin + 1); return static_cast(result); } -size_t ICACHE_RAM_ATTR cbuf::write(char c) { - if(full()) return 0; - - *_end = c; - _end = wrap_if_bufend(_end + 1); - return 1; +size_t cbuf::read(char* dst, size_t size) { + size_t bytes_available = getSize(); + size_t size_to_read = (size < bytes_available) ? size : bytes_available; + size_t size_read = size_to_read; + if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) { + size_t top_size = _bufend - _begin; + memcpy(dst, _begin, top_size); + _begin = _buf; + size_to_read -= top_size; + dst += top_size; + } + memcpy(dst, _begin, size_to_read); + _begin = wrap_if_bufend(_begin + size_to_read); + return size_read; +} + +size_t ICACHE_RAM_ATTR cbuf::write(char c) { + if(full()) + return 0; + + *_end = c; + _end = wrap_if_bufend(_end + 1); + return 1; +} + +size_t cbuf::write(const char* src, size_t size) { + size_t bytes_available = room(); + size_t size_to_write = (size < bytes_available) ? size : bytes_available; + size_t size_written = size_to_write; + if(_end >= _begin && size_to_write > (size_t) (_bufend - _end)) { + size_t top_size = _bufend - _end; + memcpy(_end, src, top_size); + _end = _buf; + size_to_write -= top_size; + src += top_size; + } + memcpy(_end, src, size_to_write); + _end = wrap_if_bufend(_end + size_to_write); + return size_written; +} + +void cbuf::flush() { + _begin = _buf; + _end = _buf; +} + +size_t cbuf::remove(size_t size) { + size_t bytes_available = getSize(); + if(size >= bytes_available) { + flush(); + return 0; + } + size_t size_to_remove = (size < bytes_available) ? size : bytes_available; + if(_end < _begin && size_to_remove > (size_t) (_bufend - _begin)) { + size_t top_size = _bufend - _begin; + _begin = _buf; + size_to_remove -= top_size; + } + _begin = wrap_if_bufend(_begin + size_to_remove); + return getSize(); } diff --git a/cores/esp8266/cbuf.h b/cores/esp8266/cbuf.h index 46f886c31..bc6372819 100644 --- a/cores/esp8266/cbuf.h +++ b/cores/esp8266/cbuf.h @@ -27,22 +27,14 @@ class cbuf { public: - cbuf(size_t size) : - _size(size), _buf(new char[size]), _bufend(_buf + size), _begin(_buf), _end(_begin) { - } - - ~cbuf() { - delete[] _buf; - } + cbuf(size_t size); + ~cbuf(); + size_t resizeAdd(size_t addSize); + size_t resize(size_t newSize); size_t getSize() const; - size_t room() const { - if(_end >= _begin) { - return _size - (_end - _begin) - 1; - } - return _begin - _end - 1; - } + size_t room() const; inline bool empty() const { return _begin == _end; @@ -52,61 +44,26 @@ class cbuf { return wrap_if_bufend(_end + 1) == _begin; } - int peek() { - if(empty()) return -1; - - return static_cast(*_begin); - } + int peek(); + size_t peek(char *dst, size_t size); int read(); - - size_t read(char* dst, size_t size) { - size_t bytes_available = getSize(); - size_t size_to_read = (size < bytes_available) ? size : bytes_available; - size_t size_read = size_to_read; - if(_end < _begin && size_to_read > (size_t)(_bufend - _begin)) { - size_t top_size = _bufend - _begin; - memcpy(dst, _begin, top_size); - _begin = _buf; - size_to_read -= top_size; - dst += top_size; - } - memcpy(dst, _begin, size_to_read); - _begin = wrap_if_bufend(_begin + size_to_read); - return size_read; - } + size_t read(char* dst, size_t size); size_t write(char c); + size_t write(const char* src, size_t size); - size_t write(const char* src, size_t size) { - size_t bytes_available = room(); - size_t size_to_write = (size < bytes_available) ? size : bytes_available; - size_t size_written = size_to_write; - if(_end >= _begin && size_to_write > (size_t)(_bufend - _end)) { - size_t top_size = _bufend - _end; - memcpy(_end, src, top_size); - _end = _buf; - size_to_write -= top_size; - src += top_size; - } - memcpy(_end, src, size_to_write); - _end = wrap_if_bufend(_end + size_to_write); - return size_written; - } - - void flush() { - _begin = _buf; - _end = _buf; - } + void flush(); + size_t remove(size_t size); private: inline char* wrap_if_bufend(char* ptr) const { return (ptr == _bufend) ? _buf : ptr; } - const size_t _size; + size_t _size; char* _buf; - const char* const _bufend; + const char* _bufend; char* _begin; char* _end; };