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