wrappedBuffer.hpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /**
  2. * wrappedBuffer.hpp for jsonstroller
  3. *
  4. * Author: isundil <isundill@gmail.com>
  5. **/
  6. #pragma once
  7. #include <stdexcept>
  8. #include <string.h>
  9. #include <string>
  10. class NotImplementedException: public std::logic_error
  11. {
  12. public:
  13. NotImplementedException(): std::logic_error("Not implemented") {};
  14. };
  15. template <typename T, int SIZE =10>
  16. class WrappedBuffer
  17. {
  18. public:
  19. WrappedBuffer();
  20. virtual ~WrappedBuffer();
  21. /**
  22. * append item(s) to buffer
  23. **/
  24. virtual void put(T item);
  25. virtual void put(T items[], unsigned int count);
  26. /**
  27. * remove last item from buffer
  28. **/
  29. void pop_back();
  30. /**
  31. * empty the buffer
  32. **/
  33. void reset();
  34. /**
  35. * @return total size appended since instanciation or clear()
  36. **/
  37. unsigned int totalSize() const;
  38. /**
  39. * @return Current size (cannot be greater than SIZE
  40. **/
  41. unsigned int size() const;
  42. /**
  43. * @return basic_string representation of the buffer
  44. **/
  45. std::basic_string<T> toString() const;
  46. T* toArray(T arr[SIZE]) const;
  47. protected:
  48. T buffer[SIZE];
  49. int curR;
  50. int curW;
  51. unsigned int written;
  52. };
  53. template<typename T, int SIZE>
  54. WrappedBuffer<T, SIZE>::WrappedBuffer(): curR(0), curW(-1)
  55. { }
  56. template<typename T, int SIZE>
  57. WrappedBuffer<T, SIZE>::~WrappedBuffer()
  58. { }
  59. template<typename T, int SIZE>
  60. void WrappedBuffer<T, SIZE>::reset()
  61. {
  62. curR = 0;
  63. curW = -1;
  64. written = 0;
  65. }
  66. template<typename T, int SIZE>
  67. unsigned int WrappedBuffer<T, SIZE>::totalSize() const
  68. { return written; }
  69. template<typename T, int SIZE>
  70. void WrappedBuffer<T, SIZE>::put(T item)
  71. {
  72. written++;
  73. if (curW +1 == SIZE)
  74. {
  75. curR = 1;
  76. curW = 0;
  77. buffer[0] = item;
  78. }
  79. else if (curW == -1)
  80. {
  81. curR = SIZE;
  82. buffer[curW = 0] = item;
  83. }
  84. else
  85. {
  86. buffer[++curW] = item;
  87. if (curR == curW)
  88. {
  89. if (++curR > SIZE)
  90. curR = 0;
  91. }
  92. }
  93. }
  94. template<typename T, int SIZE>
  95. void WrappedBuffer<T, SIZE>::put(T items[], unsigned int count)
  96. {
  97. unsigned int newSize = size() + count;
  98. if (!count)
  99. return;
  100. written += count;
  101. while (count > SIZE)
  102. {
  103. count -= SIZE;
  104. items += SIZE;
  105. }
  106. if (curW + count >= SIZE)
  107. {
  108. if (curW +1 != SIZE)
  109. {
  110. memcpy(&buffer[curW +1], items, sizeof(T) * (SIZE - curW -1));
  111. items += (SIZE - curW -1);
  112. count -= (SIZE - curW -1);
  113. }
  114. curW = -1;
  115. }
  116. memcpy(&buffer[curW +1], items, sizeof(T) * count);
  117. curW += count;
  118. if (curW == SIZE)
  119. {
  120. curW = 0;
  121. curR = 1;
  122. }
  123. else if (newSize >= SIZE)
  124. curR = (curW +1) % SIZE;
  125. }
  126. template<typename T, int SIZE>
  127. void WrappedBuffer<T, SIZE>::pop_back()
  128. {
  129. unsigned int oldSize = size();
  130. written--;
  131. if (oldSize == 0)
  132. return;
  133. else if (oldSize == 1)
  134. {
  135. curW = -1;
  136. curR = 0;
  137. }
  138. else if (--curW < 0)
  139. {
  140. curW += SIZE;
  141. }
  142. }
  143. template<typename T, int SIZE>
  144. unsigned int WrappedBuffer<T, SIZE>::size() const
  145. {
  146. if (curW == -1)
  147. return 0;
  148. return (curR > curW) ? (SIZE - curR + curW +1) : (curW - curR +1);
  149. }
  150. template<typename T, int SIZE>
  151. std::basic_string<T> WrappedBuffer<T, SIZE>::toString() const
  152. {
  153. const unsigned int size = this->size();
  154. std::basic_string<T> result;
  155. if (!size)
  156. return result;
  157. result.reserve(size);
  158. const int from = (curR == SIZE) ? 0 : curR;
  159. int i = 0;
  160. unsigned int j =0;
  161. for (i = from; (curW >= from && i <= curW) || (curW < from && i < SIZE); ++i)
  162. {
  163. j++;
  164. result += buffer[i];
  165. }
  166. i = 0;
  167. while (i <= curW && j < size)
  168. {
  169. result += buffer[i++];
  170. j++;
  171. }
  172. return result;
  173. }
  174. template<typename T, int SIZE>
  175. T* WrappedBuffer<T, SIZE>::toArray(T arr[SIZE]) const
  176. {
  177. throw NotImplementedException();
  178. if (!arr)
  179. arr = new T[SIZE]();
  180. //TODO
  181. return arr;
  182. }