#ifndef TinyGsmFifo_h
|
|
#define TinyGsmFifo_h
|
|
|
|
template <class T, unsigned N>
|
|
class TinyGsmFifo
|
|
{
|
|
public:
|
|
TinyGsmFifo()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
_r = 0;
|
|
_w = 0;
|
|
}
|
|
|
|
// writing thread/context API
|
|
//-------------------------------------------------------------
|
|
|
|
bool writeable(void)
|
|
{
|
|
return free() > 0;
|
|
}
|
|
|
|
int free(void)
|
|
{
|
|
int s = _r - _w;
|
|
if (s <= 0)
|
|
s += N;
|
|
return s - 1;
|
|
}
|
|
|
|
bool put(const T& c)
|
|
{
|
|
int i = _w;
|
|
int j = i;
|
|
i = _inc(i);
|
|
if (i == _r) // !writeable()
|
|
return false;
|
|
_b[j] = c;
|
|
_w = i;
|
|
return true;
|
|
}
|
|
|
|
int put(const T* p, int n, bool t = false)
|
|
{
|
|
int c = n;
|
|
while (c)
|
|
{
|
|
int f;
|
|
while ((f = free()) == 0) // wait for space
|
|
{
|
|
if (!t) return n - c; // no more space and not blocking
|
|
/* nothing / just wait */;
|
|
}
|
|
// check free space
|
|
if (c < f) f = c;
|
|
int w = _w;
|
|
int m = N - w;
|
|
// check wrap
|
|
if (f > m) f = m;
|
|
memcpy(&_b[w], p, f);
|
|
_w = _inc(w, f);
|
|
c -= f;
|
|
p += f;
|
|
}
|
|
return n - c;
|
|
}
|
|
|
|
// reading thread/context API
|
|
// --------------------------------------------------------
|
|
|
|
bool readable(void)
|
|
{
|
|
return (_r != _w);
|
|
}
|
|
|
|
size_t size(void)
|
|
{
|
|
int s = _w - _r;
|
|
if (s < 0)
|
|
s += N;
|
|
return s;
|
|
}
|
|
|
|
bool get(T* p)
|
|
{
|
|
int r = _r;
|
|
if (r == _w) // !readable()
|
|
return false;
|
|
*p = _b[r];
|
|
_r = _inc(r);
|
|
return true;
|
|
}
|
|
|
|
int get(T* p, int n, bool t = false)
|
|
{
|
|
int c = n;
|
|
while (c)
|
|
{
|
|
int f;
|
|
for (;;) // wait for data
|
|
{
|
|
f = size();
|
|
if (f) break; // free space
|
|
if (!t) return n - c; // no space and not blocking
|
|
/* nothing / just wait */;
|
|
}
|
|
// check available data
|
|
if (c < f) f = c;
|
|
int r = _r;
|
|
int m = N - r;
|
|
// check wrap
|
|
if (f > m) f = m;
|
|
memcpy(p, &_b[r], f);
|
|
_r = _inc(r, f);
|
|
c -= f;
|
|
p += f;
|
|
}
|
|
return n - c;
|
|
}
|
|
|
|
private:
|
|
int _inc(int i, int n = 1)
|
|
{
|
|
return (i + n) % N;
|
|
}
|
|
|
|
T _b[N];
|
|
int _w;
|
|
int _r;
|
|
};
|
|
|
|
#endif
|