COSA
An Object-Oriented Platform for Arduino Programming
IOBuffer.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_IOBUFFER_HH
22 #define COSA_IOBUFFER_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/IOStream.hh"
26 #include "Cosa/Power.hh"
27 
35 template <uint16_t SIZE>
36 class IOBuffer : public IOStream::Device {
37  static_assert(SIZE && !(SIZE & (SIZE - 1)), "SIZE should be power of 2");
38 public:
43  IOStream::Device(),
44  m_head(0),
45  m_tail(0)
46  {}
47 
52  bool is_empty()
53  __attribute__((always_inline))
54  {
55  return (m_head == m_tail);
56  }
57 
62  bool is_full()
63  __attribute__((always_inline))
64  {
65  return (((m_head + 1) & MASK) == m_tail);
66  }
67 
73  virtual int available()
74  __attribute__((always_inline))
75  {
76  return ((SIZE + m_head - m_tail) & MASK);
77  }
78 
84  virtual int room()
85  __attribute__((always_inline))
86  {
87  return ((SIZE - m_head + m_tail - 1) & MASK);
88  }
89 
96  virtual int putchar(char c);
97 
103  virtual int peekchar();
104 
111  virtual int peekchar(char c);
112 
118  virtual int getchar();
119 
125  virtual int flush();
126 
130  virtual void empty()
131  __attribute__((always_inline))
132  {
133  m_head = m_tail = 0;
134  }
135 
139  operator const char*()
140  __attribute__((always_inline))
141  {
142  return (&m_buffer[m_tail + 1]);
143  }
144 
145 private:
146  static const uint16_t MASK = (SIZE - 1);
147  volatile uint16_t m_head;
148  volatile uint16_t m_tail;
149  char m_buffer[SIZE];
150 };
151 
152 template <uint16_t SIZE>
153 int
155 {
156  uint16_t next = (m_head + 1) & MASK;
157  if (UNLIKELY(next == m_tail)) return (IOStream::EOF);
158  m_buffer[next] = c;
159  m_head = next;
160  return (c & 0xff);
161 }
162 
163 template <uint16_t SIZE>
164 int
166 {
167  if (UNLIKELY(m_head == m_tail)) return (IOStream::EOF);
168  uint16_t next = (m_tail + 1) & MASK;
169  return (m_buffer[next] & 0xff);
170 }
171 
172 template <uint16_t SIZE>
173 int
175 {
176  uint16_t tail = m_tail;
177  int res = 0;
178  while (tail != m_head) {
179  res += 1;
180  tail = (tail + 1) & MASK;
181  if (UNLIKELY(m_buffer[tail] == c)) return (res);
182  }
183  return (IOStream::EOF);
184 }
185 
186 template <uint16_t SIZE>
187 int
189 {
190  if (UNLIKELY(m_head == m_tail)) return (IOStream::EOF);
191  uint16_t next = (m_tail + 1) & MASK;
192  m_tail = next;
193  return (m_buffer[next] & 0xff);
194 }
195 
196 template <uint16_t SIZE>
197 int
199 {
200  while (m_head != m_tail) yield();
201  return (0);
202 }
203 
204 #endif
virtual void empty()
Definition: IOBuffer.hh:130
virtual int putchar(char c)
Definition: IOBuffer.hh:154
virtual int available()
Definition: IOBuffer.hh:73
bool is_full()
Definition: IOBuffer.hh:62
virtual int room()
Definition: IOBuffer.hh:84
virtual int getchar()
Definition: IOBuffer.hh:188
#define static_assert(condition, message)
Definition: Types.h:266
void(* yield)()
static const int EOF
Definition: IOStream.hh:33
IOBuffer()
Definition: IOBuffer.hh:42
bool is_empty()
Definition: IOBuffer.hh:52
virtual int peekchar()
Definition: IOBuffer.hh:165
#define UNLIKELY(x)
Definition: Types.h:153
virtual int flush()
Definition: IOBuffer.hh:198