add stop service
[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         count = 0;
35         // constructor for queues based on ring buffers
36         // create the first link
37         T initialvalue;
38         lastFree = new link<T>( initialvalue );
39         lastFilled = lastFree;
40         // make value point to itself
41         lastFilled->nextLink = lastFilled;
42         lastFilled->prevLink = lastFilled;
43         // now add the remainder of the elements
44         while ( max-- > 0 )
45         {
46                 link<T> * newLink = new link<T>( initialvalue );
47                 newLink->prevLink = lastFilled;
48                 newLink->nextLink = lastFilled->nextLink;
49                 lastFilled->nextLink->prevLink = newLink;
50                 lastFilled->nextLink = newLink;
51         }
52 }
53
54 template <class T>
55 queueRingBuffer<T>::~queueRingBuffer()
56 {
57         // delete all memory associated with ring buffer
58         link<T> * p = lastFree;
59         link<T> * next;
60
61         // walk around the circle deleting nodes
62         while( p->nextLink != lastFree )
63         {
64                 next = p->nextLink;
65                 delete p;
66                 p = next;
67         }
68 }
69
70 template <class T>
71 T& queueRingBuffer<T>::dequeue()
72 {
73         // remove element form front of queue
74         // advance last free position
75         lastFree = lastFree->nextLink;
76         count--;
77         // return value stored in last free position
78         return lastFree->value;
79 }
80
81 template <class T>
82 T& queueRingBuffer<T>::current()
83 {
84         // return value stored in current
85         return lastFree->nextLink->value;
86 }
87
88 template <class T>
89 void queueRingBuffer<T>::enqueue( const T &val )
90 {
91         // add new element to end of queue buffer
92         // first check for potential overflow
93         if( lastFilled->nextLink == lastFree )
94         {
95 //              eDebug("increase size %d", count);
96                 link<T> * newLink = new link<T>( val );
97                 newLink->prevLink = lastFilled;
98                 newLink->nextLink = lastFilled->nextLink;
99                 lastFilled->nextLink->prevLink = newLink;
100                 lastFilled->nextLink = newLink;
101         }
102         else
103         {
104                 // simply advance the last filled pointer
105                 lastFilled = lastFilled->nextLink;
106                 lastFilled->value = val;
107         }
108         count++;
109 }
110 #endif