|
|
- #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
|