--- /dev/null
+#include "WindowedFifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::WindowedFifo(unsigned size = 20) {\r
+ //std::cout << "Create WindowedFifo." << std::endl;\r
+ _size = size;\r
+ _buffer = new char[_size];\r
+ _head = 0;\r
+ _tail = 0;\r
+ _headRoom = 0;\r
+ _tailRoom = 0;\r
+ _use = 0;\r
+ //indicates whether Fifo is empty or full if _head == _tail\r
+ //_isFull = false;\r
+ _isHeadReserved = false;\r
+ _isTailReserved = false;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::~WindowedFifo() {\r
+ //std::cout << "Delete WindowedFifo." << std::endl;\r
+ if (_buffer) {\r
+ delete _buffer;\r
+ }\r
+ _buffer = 0;\r
+ _head = 0;\r
+ _tail = 0;\r
+ _use = 0;\r
+ //std::cout << "Deleted WindowedFifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::reserve(void** dest, unsigned len) {\r
+ char** destination = (char**)dest;\r
+ //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;\r
+\r
+ //can only reserve once piece at a time\r
+ if (_isHeadReserved) {\r
+ *destination = 0;\r
+ return 0;\r
+ }\r
+\r
+ //reserve at most as much memory as still available in the buffer\r
+ unsigned write = (len <= _size - _use ? len : _size - _use);\r
+\r
+ if (write > 0) {\r
+ //if wrap-around in buffer: return only buffer for the\r
+ //contiguous buffer space\r
+ if (_head + write > _size) {\r
+ write = _size - _head;\r
+ }\r
+\r
+ _headRoom = (_head + write) == _size? 0 : _head + write;\r
+ *destination = &(_buffer[_head]);\r
+ _isHeadReserved = true;\r
+ }\r
+\r
+ //std::cout << "Reserved " << write << " bytes." << std::endl;\r
+ _writeReserve = write; \r
+ return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::release() {\r
+ if (_isHeadReserved) {\r
+ //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;\r
+ _head = _headRoom;\r
+ _use += _writeReserve;\r
+ _isHeadReserved = false;\r
+ }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::capture(void **dest, unsigned len) {\r
+ char** destination = (char**)dest;\r
+ //std::cout << "Attempt to capture " << len << " bytes." << std::endl;\r
+\r
+ if (_isTailReserved) {\r
+ //std::cout << "Only one attempt to capture allowed." << std::endl;\r
+ *destination = 0;\r
+ return 0;\r
+ }\r
+\r
+ //capture at most as much data as available in the buffer\r
+ unsigned read = (len <= _use ? len : _use);\r
+\r
+ if (read > 0) {\r
+ //if wrap-around in buffer: return only buffer for the\r
+ //conntiguous buffer space\r
+ if (_tail + read> _size) {\r
+ read = _size - _tail;\r
+ }\r
+\r
+ _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;\r
+ *destination = &(_buffer[_tail]);\r
+ _isTailReserved = true;\r
+ }\r
+\r
+ //std::cout << "Captured " << read << " bytes." << std::endl;\r
+\r
+ _readReserve = read; \r
+ return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::consume() {\r
+ if (_isTailReserved) {\r
+ //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;\r
+ _tail = _tailRoom;\r
+ _use -= _readReserve;\r
+ _isTailReserved = false;\r
+ }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::size() const {\r
+ return _size;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::unused() const {\r
+ return _size - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::used() const {\r
+ return _use;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+#include <iostream>\r
+#include <iomanip>\r
+using namespace std;\r
+\r
+int main() {\r
+ WindowedFifo *myFifo = new WindowedFifo(16);\r
+\r
+ int* buf1;\r
+ int* buf2;\r
+ int x = myFifo->reserve((void**)&buf1, 8);\r
+ *buf1 = 10;\r
+ *(buf1 + 1) = 20;\r
+ myFifo->release();\r
+ int y = myFifo->capture((void**)&buf2, 8);\r
+ std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;\r
+ myFifo->consume();\r
+\r
+ for (int j = 0; j < 3; j++) {\r
+ for (int i = 0; i < 6; i++) {\r
+ std::cout << "write " << i << " to Fifo. ";\r
+ int write = myFifo->reserve((void**)&buf1, sizeof(int));\r
+ if (write == sizeof(int)) {\r
+ *buf1 = i;\r
+ myFifo->release();\r
+ std::cout << "used: " << std::setw(2) << myFifo->used()\r
+ << ", unused: " << std::setw(2) << myFifo->unused()\r
+ << ", size: " << std::setw(2) << myFifo->size()\r
+ << std::endl;\r
+ } else {\r
+ std::cout << std::endl;\r
+ }\r
+ }\r
+ for (int i = 0; i < 16; i++) {\r
+ char* buf3;\r
+ int read = myFifo->capture((void**)&buf3, sizeof(char));\r
+ if (read == sizeof(char)) {\r
+ std::cout << "read " << (unsigned)*buf3 << " from Fifo ";\r
+ std::cout << "used: " << std::setw(2) << myFifo->used()\r
+ << ", unused: " << std::setw(2) << myFifo->unused()\r
+ << ", size: " << std::setw(2) << myFifo->size()\r
+ << std::endl;\r
+ myFifo->consume();\r
+ } else {\r
+ std::cout << "read nothing from Fifo." << std::endl;\r
+ }\r
+\r
+ }\r
+ }\r
+ delete myFifo;\r
+ return 0;\r
+}\r
+*/\r