f2cd9058805ed340985fca482686441db5af55dc
[enigma2.git] / lib / base / ringbuffer.h
1 #ifndef QueueRingBufferH
2 #define QueueRingBufferH
3
4 template <class T>
5 class queueRingBuffer
6 {
7         template <class A>
8         struct link
9         {
10                 link ( const A &val )
11                         :value(val)
12                 {}
13                 A value;
14                 link *nextLink;
15                 link *prevLink;
16         };
17
18         link<T> *lastFilled;
19         link<T> *lastFree;
20         unsigned int max;
21         int count;
22 public:
23         queueRingBuffer( unsigned int max );
24         ~queueRingBuffer();
25         int size() { return count; }
26         T& queueRingBuffer::dequeue();
27         T& queueRingBuffer::current();
28         void queueRingBuffer::enqueue( const T &val );
29 };
30
31 template <class T>
32 queueRingBuffer<T>::queueRingBuffer( unsigned int max )
33 {
34         // constructor for queues based on ring buffers
35         // create the first link
36         T initialvalue;
37         lastFree = new link<T>( initialvalue );
38         lastFilled = lastFree;
39         // make value point to itself
40         lastFilled->nextLink = lastFilled;
41         lastFilled->prevLink = lastFilled;
42         // now add the remainder of the elements
43         while ( max-- > 0 )
44         {
45                 link<T> * newLink = new link<T>( initialvalue );
46                 newLink->prevLink = lastFilled;
47                 newLink->nextLink = lastFilled->nextLink;
48                 lastFilled->nextLink->prevLink = newLink;
49                 lastFilled->nextLink = newLink;
50         }
51 }
52
53 template <class T>
54 queueRingBuffer<T>::~queueRingBuffer()
55 {
56         // delete all memory associated with ring buffer
57         link<T> * p = lastFree;
58         link<T> * next;
59
60         // walk around the circle deleting nodes
61         while( p->nextLink != lastFree )
62         {
63                 next = p->nextLink;
64                 delete p;
65                 p = next;
66         }
67 }
68
69 template <class T>
70 T& queueRingBuffer<T>::dequeue()
71 {
72         // remove element form front of queue
73         // advance last free position
74         lastFree = lastFree->nextLink;
75         count--;
76         // return value stored in last free position
77         return lastFree->value;
78 }
79
80 template <class T>
81 T& queueRingBuffer<T>::current()
82 {
83         // return value stored in current
84         return lastFree->nextLink->value;
85 }
86
87 template <class T>
88 void queueRingBuffer<T>::enqueue( const T &val )
89 {
90         // add new element to end of queue buffer
91         // first check for potential overflow
92         if( lastFilled->nextLink == lastFree )
93         {
94                 eDebug("increase size %d", count);
95                 link<T> * newLink = new link<T>( val );
96                 newLink->prevLink = lastFilled;
97                 newLink->nextLink = lastFilled->nextLink;
98                 lastFilled->nextLink->prevLink = newLink;
99                 lastFilled->nextLink = newLink;
100         }
101         else
102         {
103                 // simply advance the last filled pointer
104                 lastFilled = lastFilled->nextLink;
105                 lastFilled->value = val;
106         }
107         count++;
108 }
109 #endif