ESP8266
cbuf.h
1 /*
2  cbuf.h - Circular buffer implementation
3  Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
4  This file is part of the esp8266 core for Arduino environment.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef __cbuf_h
22 #define __cbuf_h
23 
24 #include <stdint.h>
25 class cbuf {
26  public:
27  cbuf(size_t size) :
28  _size(size), _buf(new char[size]), _bufend(_buf + size), _begin(_buf), _end(_begin) {
29  }
30 
31  ~cbuf() {
32  delete[] _buf;
33  }
34 
35  size_t getSize() const {
36  if(_end >= _begin) return _end - _begin;
37 
38  return _size - (_begin - _end);
39  }
40 
41  size_t room() const {
42  if(_end >= _begin) {
43  return _size - (_end - _begin) - 1;
44  }
45  return _begin - _end - 1;
46  }
47 
48  bool empty() const {
49  return _begin == _end;
50  }
51 
52  int peek() {
53  if(_end == _begin) return -1;
54 
55  return static_cast<int>(*_begin);
56  }
57 
58  int read() {
59  if(getSize() == 0) return -1;
60 
61  char result = *_begin;
63  return static_cast<int>(result);
64  }
65 
66  size_t read(char* dst, size_t size) {
67  size_t bytes_available = getSize();
68  size_t size_to_read = (size < bytes_available) ? size : bytes_available;
69  size_t size_read = size_to_read;
70  if(_end < _begin && size_to_read > (size_t)(_bufend - _begin)) {
71  size_t top_size = _bufend - _begin;
72  memcpy(dst, _begin, top_size);
73  _begin = _buf;
74  size_to_read -= top_size;
75  dst += top_size;
76  }
77  memcpy(dst, _begin, size_to_read);
78  _begin = wrap_if_bufend(_begin + size_to_read);
79  return size_read;
80  }
81 
82  size_t write(char c) {
83  if(room() == 0) return 0;
84 
85  *_end = c;
86  _end = wrap_if_bufend(_end + 1);
87  return 1;
88  }
89 
90  size_t write(const char* src, size_t size) {
91  size_t bytes_available = room();
92  size_t size_to_write = (size < bytes_available) ? size : bytes_available;
93  size_t size_written = size_to_write;
94  if(_end >= _begin && size_to_write > (size_t)(_bufend - _end)) {
95  size_t top_size = _bufend - _end;
96  memcpy(_end, src, top_size);
97  _end = _buf;
98  size_to_write -= top_size;
99  src += top_size;
100  }
101  memcpy(_end, src, size_to_write);
102  _end = wrap_if_bufend(_end + size_to_write);
103  return size_written;
104  }
105 
106  void flush() {
107  _begin = _buf;
108  _end = _buf;
109  }
110 
111  private:
112  inline char* wrap_if_bufend(char* ptr) {
113  return (ptr == _bufend) ? _buf : ptr;
114  }
115 
116  const size_t _size;
117  char* _buf;
118  const char* const _bufend;
119  char* _begin;
120  char* _end;
121 };
122 
123 #endif//__cbuf_h
char * wrap_if_bufend(char *ptr)
Definition: cbuf.h:112
size_t write(const char *src, size_t size)
Definition: cbuf.h:90
~cbuf()
Definition: cbuf.h:31
size_t write(char c)
Definition: cbuf.h:82
const size_t _size
Definition: cbuf.h:116
void flush()
Definition: cbuf.h:106
char * _end
Definition: cbuf.h:120
cbuf(size_t size)
Definition: cbuf.h:27
char * _buf
Definition: cbuf.h:117
const char *const _bufend
Definition: cbuf.h:118
int peek()
Definition: cbuf.h:52
char * _begin
Definition: cbuf.h:119
size_t room() const
Definition: cbuf.h:41
size_t read(char *dst, size_t size)
Definition: cbuf.h:66
bool empty() const
Definition: cbuf.h:48
size_t getSize() const
Definition: cbuf.h:35
int read()
Definition: cbuf.h:58
Definition: cbuf.h:25