t3
Fork of C027_Support by
Pipe.h@21:c4d64830bf02, 2014-04-08 (annotated)
- Committer:
- mazgch
- Date:
- Tue Apr 08 09:15:37 2014 +0000
- Revision:
- 21:c4d64830bf02
- Parent:
- 13:e2446fcdc246
- Child:
- 40:295099ff5338
improved modem library (network, sockets, sms, ussd)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mazgch | 0:cb2d45baaca3 | 1 | #pragma once |
mazgch | 0:cb2d45baaca3 | 2 | |
mazgch | 0:cb2d45baaca3 | 3 | template <class T> |
mazgch | 0:cb2d45baaca3 | 4 | class Pipe |
mazgch | 0:cb2d45baaca3 | 5 | { |
mazgch | 0:cb2d45baaca3 | 6 | private: |
mazgch | 0:cb2d45baaca3 | 7 | inline int _inc(int i, int n = 1) |
mazgch | 0:cb2d45baaca3 | 8 | { |
mazgch | 0:cb2d45baaca3 | 9 | i += n; |
mazgch | 9:e7a5959ffae1 | 10 | if (i >= _s) |
mazgch | 9:e7a5959ffae1 | 11 | i -= _s; |
mazgch | 0:cb2d45baaca3 | 12 | return i; |
mazgch | 0:cb2d45baaca3 | 13 | } |
mazgch | 0:cb2d45baaca3 | 14 | public: |
mazgch | 9:e7a5959ffae1 | 15 | Pipe(int n, T* b = NULL) |
mazgch | 0:cb2d45baaca3 | 16 | { |
mazgch | 9:e7a5959ffae1 | 17 | _a = b ? NULL : new T[n]; |
mazgch | 9:e7a5959ffae1 | 18 | _r = 0; |
mazgch | 9:e7a5959ffae1 | 19 | _w = 0; |
mazgch | 9:e7a5959ffae1 | 20 | _b = b ? b : _a; |
mazgch | 9:e7a5959ffae1 | 21 | _s = n; |
mazgch | 0:cb2d45baaca3 | 22 | } |
mazgch | 13:e2446fcdc246 | 23 | virtual ~Pipe(void) |
mazgch | 0:cb2d45baaca3 | 24 | { |
mazgch | 9:e7a5959ffae1 | 25 | if (_a) |
mazgch | 9:e7a5959ffae1 | 26 | delete [] _a; |
mazgch | 0:cb2d45baaca3 | 27 | } |
mazgch | 21:c4d64830bf02 | 28 | void dump(void) |
mazgch | 21:c4d64830bf02 | 29 | { |
mazgch | 21:c4d64830bf02 | 30 | int o = _r; |
mazgch | 21:c4d64830bf02 | 31 | printf("pipe: %d/%d ", size(), _s); |
mazgch | 21:c4d64830bf02 | 32 | while (o != _w) { |
mazgch | 21:c4d64830bf02 | 33 | T t = _b[o]; |
mazgch | 21:c4d64830bf02 | 34 | printf("%0*X", sizeof(T)*2, t); |
mazgch | 21:c4d64830bf02 | 35 | o = _inc(o); |
mazgch | 21:c4d64830bf02 | 36 | } |
mazgch | 21:c4d64830bf02 | 37 | printf("\n"); |
mazgch | 21:c4d64830bf02 | 38 | } |
mazgch | 0:cb2d45baaca3 | 39 | // writing thread |
mazgch | 0:cb2d45baaca3 | 40 | bool writeable(void) // = not full |
mazgch | 0:cb2d45baaca3 | 41 | { |
mazgch | 9:e7a5959ffae1 | 42 | return free() > 0; |
mazgch | 0:cb2d45baaca3 | 43 | } |
mazgch | 0:cb2d45baaca3 | 44 | int free(void) // number of elements that can be added |
mazgch | 0:cb2d45baaca3 | 45 | { |
mazgch | 9:e7a5959ffae1 | 46 | int s = _r - _w; |
mazgch | 9:e7a5959ffae1 | 47 | if (s <= 0) |
mazgch | 9:e7a5959ffae1 | 48 | s += _s; |
mazgch | 9:e7a5959ffae1 | 49 | return s - 1; |
mazgch | 0:cb2d45baaca3 | 50 | } |
mazgch | 13:e2446fcdc246 | 51 | T putc(T c) |
mazgch | 0:cb2d45baaca3 | 52 | { |
mazgch | 9:e7a5959ffae1 | 53 | int i = _w; |
mazgch | 0:cb2d45baaca3 | 54 | int j = i; |
mazgch | 0:cb2d45baaca3 | 55 | i = _inc(i); |
mazgch | 9:e7a5959ffae1 | 56 | while (i == _r) // = !writeable() |
mazgch | 9:e7a5959ffae1 | 57 | /*wait for space*/; |
mazgch | 9:e7a5959ffae1 | 58 | _b[j] = c; |
mazgch | 13:e2446fcdc246 | 59 | _w = i; |
mazgch | 13:e2446fcdc246 | 60 | return c; |
mazgch | 0:cb2d45baaca3 | 61 | } |
mazgch | 9:e7a5959ffae1 | 62 | int put(const T* p, int n, bool t = false) |
mazgch | 0:cb2d45baaca3 | 63 | { |
mazgch | 9:e7a5959ffae1 | 64 | int c = n; |
mazgch | 9:e7a5959ffae1 | 65 | while (c) |
mazgch | 0:cb2d45baaca3 | 66 | { |
mazgch | 9:e7a5959ffae1 | 67 | int f; |
mazgch | 9:e7a5959ffae1 | 68 | for (;;) // wait for space |
mazgch | 0:cb2d45baaca3 | 69 | { |
mazgch | 9:e7a5959ffae1 | 70 | f = free(); |
mazgch | 9:e7a5959ffae1 | 71 | if (f) break; // data avail |
mazgch | 9:e7a5959ffae1 | 72 | if (!t) return n - c; // no more space and not blocking |
mazgch | 0:cb2d45baaca3 | 73 | } |
mazgch | 9:e7a5959ffae1 | 74 | // check free space |
mazgch | 9:e7a5959ffae1 | 75 | if (c < f) f = c; |
mazgch | 9:e7a5959ffae1 | 76 | int w = _w; |
mazgch | 9:e7a5959ffae1 | 77 | int m = _s - w; |
mazgch | 9:e7a5959ffae1 | 78 | // check wrap |
mazgch | 9:e7a5959ffae1 | 79 | if (f > m) f = m; |
mazgch | 9:e7a5959ffae1 | 80 | memcpy(&_b[w], p, f); |
mazgch | 9:e7a5959ffae1 | 81 | _w = _inc(w, f); |
mazgch | 9:e7a5959ffae1 | 82 | c -= f; |
mazgch | 9:e7a5959ffae1 | 83 | p += f; |
mazgch | 8:2435cdff8015 | 84 | } |
mazgch | 9:e7a5959ffae1 | 85 | return n - c; |
mazgch | 0:cb2d45baaca3 | 86 | } |
mazgch | 0:cb2d45baaca3 | 87 | // reading thread |
mazgch | 0:cb2d45baaca3 | 88 | // -------------------------------------------------------- |
mazgch | 0:cb2d45baaca3 | 89 | //! check if there are any values available |
mazgch | 0:cb2d45baaca3 | 90 | bool readable(void) // = not empty |
mazgch | 0:cb2d45baaca3 | 91 | { |
mazgch | 9:e7a5959ffae1 | 92 | return (_r != _w); |
mazgch | 0:cb2d45baaca3 | 93 | } |
mazgch | 0:cb2d45baaca3 | 94 | //! get the number of values avialable in the buffer |
mazgch | 2:b6012cd91657 | 95 | virtual int size(void) |
mazgch | 0:cb2d45baaca3 | 96 | { |
mazgch | 9:e7a5959ffae1 | 97 | int s = _w - _r; |
mazgch | 9:e7a5959ffae1 | 98 | if (s < 0) |
mazgch | 9:e7a5959ffae1 | 99 | s += _s; |
mazgch | 9:e7a5959ffae1 | 100 | return s; |
mazgch | 0:cb2d45baaca3 | 101 | } |
mazgch | 0:cb2d45baaca3 | 102 | //! get a value from buffer (this function will block if no values available) |
mazgch | 0:cb2d45baaca3 | 103 | T getc(void) |
mazgch | 0:cb2d45baaca3 | 104 | { |
mazgch | 9:e7a5959ffae1 | 105 | int r = _r; |
mazgch | 9:e7a5959ffae1 | 106 | while (r == _w) // = !readable() |
mazgch | 9:e7a5959ffae1 | 107 | /*wait for data*/; |
mazgch | 9:e7a5959ffae1 | 108 | T t = _b[r]; |
mazgch | 9:e7a5959ffae1 | 109 | _r = _inc(r); |
mazgch | 0:cb2d45baaca3 | 110 | return t; |
mazgch | 0:cb2d45baaca3 | 111 | } |
mazgch | 9:e7a5959ffae1 | 112 | //! get values from buffer |
mazgch | 9:e7a5959ffae1 | 113 | virtual int get(T* p, int n, bool t = false) |
mazgch | 0:cb2d45baaca3 | 114 | { |
mazgch | 9:e7a5959ffae1 | 115 | int c = n; |
mazgch | 9:e7a5959ffae1 | 116 | while (c) |
mazgch | 0:cb2d45baaca3 | 117 | { |
mazgch | 9:e7a5959ffae1 | 118 | int f; |
mazgch | 9:e7a5959ffae1 | 119 | for (;;) // wait for data |
mazgch | 0:cb2d45baaca3 | 120 | { |
mazgch | 9:e7a5959ffae1 | 121 | f = size(); |
mazgch | 9:e7a5959ffae1 | 122 | if (f) break; // free space |
mazgch | 9:e7a5959ffae1 | 123 | if (!t) return n - c; // no space and not blocking |
mazgch | 0:cb2d45baaca3 | 124 | } |
mazgch | 9:e7a5959ffae1 | 125 | // check available data |
mazgch | 9:e7a5959ffae1 | 126 | if (c < f) f = c; |
mazgch | 9:e7a5959ffae1 | 127 | int r = _r; |
mazgch | 9:e7a5959ffae1 | 128 | int m = _s - r; |
mazgch | 9:e7a5959ffae1 | 129 | // check wrap |
mazgch | 9:e7a5959ffae1 | 130 | if (f > m) f = m; |
mazgch | 9:e7a5959ffae1 | 131 | memcpy(p, &_b[r], f); |
mazgch | 9:e7a5959ffae1 | 132 | _r = _inc(r, f); |
mazgch | 9:e7a5959ffae1 | 133 | c -= f; |
mazgch | 9:e7a5959ffae1 | 134 | p += f; |
mazgch | 0:cb2d45baaca3 | 135 | } |
mazgch | 9:e7a5959ffae1 | 136 | return n - c; |
mazgch | 0:cb2d45baaca3 | 137 | } |
mazgch | 9:e7a5959ffae1 | 138 | |
mazgch | 0:cb2d45baaca3 | 139 | // the following functions are useful if you like to inspect or parse the buffer |
mazgch | 9:e7a5959ffae1 | 140 | |
mazgch | 9:e7a5959ffae1 | 141 | //! reset the parsing index and return the number of available elments |
mazgch | 21:c4d64830bf02 | 142 | virtual int set(int ix) |
mazgch | 9:e7a5959ffae1 | 143 | { |
mazgch | 21:c4d64830bf02 | 144 | int sz = size(); |
mazgch | 21:c4d64830bf02 | 145 | ix = (ix > sz) ? sz : ix; |
mazgch | 21:c4d64830bf02 | 146 | _o = _inc(_r, ix); |
mazgch | 21:c4d64830bf02 | 147 | return sz - ix; |
mazgch | 9:e7a5959ffae1 | 148 | } |
mazgch | 9:e7a5959ffae1 | 149 | //! get the next element and increment |
mazgch | 9:e7a5959ffae1 | 150 | virtual T next(void) |
mazgch | 9:e7a5959ffae1 | 151 | { |
mazgch | 9:e7a5959ffae1 | 152 | int o = _o; |
mazgch | 9:e7a5959ffae1 | 153 | T t = _b[o]; |
mazgch | 9:e7a5959ffae1 | 154 | _o = _inc(o); |
mazgch | 9:e7a5959ffae1 | 155 | return t; |
mazgch | 9:e7a5959ffae1 | 156 | } |
mazgch | 9:e7a5959ffae1 | 157 | //! commit the index |
mazgch | 9:e7a5959ffae1 | 158 | virtual void done(void) |
mazgch | 9:e7a5959ffae1 | 159 | { |
mazgch | 9:e7a5959ffae1 | 160 | _r = _o; |
mazgch | 9:e7a5959ffae1 | 161 | } |
mazgch | 0:cb2d45baaca3 | 162 | |
mazgch | 0:cb2d45baaca3 | 163 | private: |
mazgch | 9:e7a5959ffae1 | 164 | T* _b; //!< buffer |
mazgch | 9:e7a5959ffae1 | 165 | T* _a; //!< allocated buffer |
mazgch | 9:e7a5959ffae1 | 166 | int _s; //!< size of buffer (s - 1) elements can be stored |
mazgch | 9:e7a5959ffae1 | 167 | volatile int _w; //!< write index |
mazgch | 9:e7a5959ffae1 | 168 | volatile int _r; //!< read index |
mazgch | 9:e7a5959ffae1 | 169 | int _o; //!< offest index used by parsing functions |
mazgch | 0:cb2d45baaca3 | 170 | }; |