* add C027_Support fork
Fork of C027_Support by
Pipe.h
- Committer:
- mazgch
- Date:
- 2014-04-08
- Revision:
- 21:c4d64830bf02
- Parent:
- 13:e2446fcdc246
- Child:
- 40:295099ff5338
File content as of revision 21:c4d64830bf02:
#pragma once template <class T> class Pipe { private: inline int _inc(int i, int n = 1) { i += n; if (i >= _s) i -= _s; return i; } public: Pipe(int n, T* b = NULL) { _a = b ? NULL : new T[n]; _r = 0; _w = 0; _b = b ? b : _a; _s = n; } virtual ~Pipe(void) { if (_a) delete [] _a; } void dump(void) { int o = _r; printf("pipe: %d/%d ", size(), _s); while (o != _w) { T t = _b[o]; printf("%0*X", sizeof(T)*2, t); o = _inc(o); } printf("\n"); } // writing thread bool writeable(void) // = not full { return free() > 0; } int free(void) // number of elements that can be added { int s = _r - _w; if (s <= 0) s += _s; return s - 1; } T putc(T c) { int i = _w; int j = i; i = _inc(i); while (i == _r) // = !writeable() /*wait for space*/; _b[j] = c; _w = i; return c; } int put(const T* p, int n, bool t = false) { int c = n; while (c) { int f; for (;;) // wait for space { f = free(); if (f) break; // data avail if (!t) return n - c; // no more space and not blocking } // check free space if (c < f) f = c; int w = _w; int m = _s - 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 // -------------------------------------------------------- //! check if there are any values available bool readable(void) // = not empty { return (_r != _w); } //! get the number of values avialable in the buffer virtual int size(void) { int s = _w - _r; if (s < 0) s += _s; return s; } //! get a value from buffer (this function will block if no values available) T getc(void) { int r = _r; while (r == _w) // = !readable() /*wait for data*/; T t = _b[r]; _r = _inc(r); return t; } //! get values from buffer virtual 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 } // check available data if (c < f) f = c; int r = _r; int m = _s - r; // check wrap if (f > m) f = m; memcpy(p, &_b[r], f); _r = _inc(r, f); c -= f; p += f; } return n - c; } // the following functions are useful if you like to inspect or parse the buffer //! reset the parsing index and return the number of available elments virtual int set(int ix) { int sz = size(); ix = (ix > sz) ? sz : ix; _o = _inc(_r, ix); return sz - ix; } //! get the next element and increment virtual T next(void) { int o = _o; T t = _b[o]; _o = _inc(o); return t; } //! commit the index virtual void done(void) { _r = _o; } private: T* _b; //!< buffer T* _a; //!< allocated buffer int _s; //!< size of buffer (s - 1) elements can be stored volatile int _w; //!< write index volatile int _r; //!< read index int _o; //!< offest index used by parsing functions };