You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
2.6 KiB

  1. #ifndef TinyGsmFifo_h
  2. #define TinyGsmFifo_h
  3. template <class T, unsigned N>
  4. class TinyGsmFifo
  5. {
  6. public:
  7. TinyGsmFifo()
  8. {
  9. clear();
  10. }
  11. void clear()
  12. {
  13. _r = 0;
  14. _w = 0;
  15. }
  16. // writing thread/context API
  17. //-------------------------------------------------------------
  18. bool writeable(void)
  19. {
  20. return free() > 0;
  21. }
  22. int free(void)
  23. {
  24. int s = _r - _w;
  25. if (s <= 0)
  26. s += N;
  27. return s - 1;
  28. }
  29. bool put(const T& c)
  30. {
  31. int i = _w;
  32. int j = i;
  33. i = _inc(i);
  34. if (i == _r) // !writeable()
  35. return false;
  36. _b[j] = c;
  37. _w = i;
  38. return true;
  39. }
  40. int put(const T* p, int n, bool t = false)
  41. {
  42. int c = n;
  43. while (c)
  44. {
  45. int f;
  46. while ((f = free()) == 0) // wait for space
  47. {
  48. if (!t) return n - c; // no more space and not blocking
  49. /* nothing / just wait */;
  50. }
  51. // check free space
  52. if (c < f) f = c;
  53. int w = _w;
  54. int m = N - w;
  55. // check wrap
  56. if (f > m) f = m;
  57. memcpy(&_b[w], p, f);
  58. _w = _inc(w, f);
  59. c -= f;
  60. p += f;
  61. }
  62. return n - c;
  63. }
  64. // reading thread/context API
  65. // --------------------------------------------------------
  66. bool readable(void)
  67. {
  68. return (_r != _w);
  69. }
  70. size_t size(void)
  71. {
  72. int s = _w - _r;
  73. if (s < 0)
  74. s += N;
  75. return s;
  76. }
  77. bool get(T* p)
  78. {
  79. int r = _r;
  80. if (r == _w) // !readable()
  81. return false;
  82. *p = _b[r];
  83. _r = _inc(r);
  84. return true;
  85. }
  86. int get(T* p, int n, bool t = false)
  87. {
  88. int c = n;
  89. while (c)
  90. {
  91. int f;
  92. for (;;) // wait for data
  93. {
  94. f = size();
  95. if (f) break; // free space
  96. if (!t) return n - c; // no space and not blocking
  97. /* nothing / just wait */;
  98. }
  99. // check available data
  100. if (c < f) f = c;
  101. int r = _r;
  102. int m = N - r;
  103. // check wrap
  104. if (f > m) f = m;
  105. memcpy(p, &_b[r], f);
  106. _r = _inc(r, f);
  107. c -= f;
  108. p += f;
  109. }
  110. return n - c;
  111. }
  112. private:
  113. int _inc(int i, int n = 1)
  114. {
  115. return (i + n) % N;
  116. }
  117. T _b[N];
  118. int _w;
  119. int _r;
  120. };
  121. #endif