3 yet another circle buffer
8 #ifndef __VECTORBUFFER_H__
9 #define __VECTORBUFFER_H__
13 #define VECPANIC(x) VectorPanic(x, __LINE__)
14 void VectorPanic(TInt, TInt);
19 NONSHARABLE_CLASS(TNodeBuffer)
23 NONSHARABLE_CLASS(TNode)
26 static TNode* Empty(TUint8* iBuffer);
27 static TNode* New(TNode* aPrev, const TDesC8& aData);
28 const TUint8* Ptr() const;
31 static void SetSucc(TNode*& aNode);
32 void Terminator(TNode* aNode);
38 inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ()
44 NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer
48 TInt Append(const TDesC8& aData);
49 // TInt AppendOverwrite(const TDesC8& aData);
51 TPtrC8 operator[](TInt aIndex) const;
54 TInt GetRoom(TInt aSize) const;
55 TInt Unreserved() const;
64 TVectorBuffer<C>::TVectorBuffer() : iSize(0)
66 Mem::FillZ(iBuffer, C);
67 iTop = TNode::Empty(iBuffer); //these points to buffer
68 iBottom = TNode::Empty(iBuffer);
72 TInt TVectorBuffer<C>::Unreserved() const
74 __ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt));
75 const TInt bytesbetween =
76 reinterpret_cast<const TUint8*>(iBottom->Succ()) -
77 reinterpret_cast<const TUint8*>(iTop);
78 const TInt topsize = sizeof(TNode);
79 if(bytesbetween > 0) //bytesbetween is room between bottom and top
80 { //therefore free room is subracted from free space
82 const TInt room = C - bytesbetween - topsize;
93 const TInt room = -bytesbetween - topsize; //free is space between pointers
98 TInt TVectorBuffer<C>::GetRoom(TInt aSize) const
100 const TInt bytesnew = sizeof(TNode) + aSize;
101 const TInt room = Unreserved() - bytesnew;
106 TInt TVectorBuffer<C>::Append(const TDesC8& aData) //ei ole ok!
108 const TInt len = aData.Length();
113 if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode)))))
116 // RDebug::Print(_L("vector: append"));
117 TNode* p = TNode::Empty(iBuffer);
118 iBottom->Terminator(p);
120 return Append(aData);
122 // iBottom = TNode::New(p, aData); //just append something into end
127 iBottom = TNode::New(iBottom, aData);
135 TInt TVectorBuffer<C>::AppendOverwrite(const TDesC8& aData) //ei ole ok!
137 while(Append(aData) == KErrOverflow)
139 if(iTop->Succ() == NULL)
141 return KErrUnderflow;
143 //Shift(); //data is lost
149 TPtrC8 TVectorBuffer<C>::Shift()
151 __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
157 iSize -= node->Size();
158 return TPtrC8(node->Ptr(), node->Size());
162 // RDebug::Print(_L("vector: shift"));
163 return Shift(); //this happens when buffer is terminated, and data lies in next
168 TInt TVectorBuffer<C>::Size() const
174 TPtrC8 TVectorBuffer<C>::operator[](TInt aIndex) const
177 TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator
178 while(index < aIndex)
180 TNode* nt = t->Succ();
188 __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
194 template <class T, TInt C>
195 NONSHARABLE_CLASS(TVector) : public TVectorBuffer<C * sizeof(T)>
199 TInt Append(const T& aData);
202 const T& operator[](TInt aIndex) const;
205 template <class T, TInt C>
206 TVector<T, C>::TVector() : TVectorBuffer<C * sizeof(T)>()
210 template <class T, TInt C>
211 TInt TVector<T, C>::Append(const T& aData)
213 const TPckgC<T> data(aData);
214 return TVectorBuffer<C * sizeof(T)>::Append(data);
217 template <class T, TInt C>
218 const T& TVector<T, C>::Shift()
220 const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::Shift();
221 return *(reinterpret_cast<const T*>(ptr.Ptr()));
225 template <class T, TInt C>
226 TInt TVector<T, C>::Size() const
228 return TVectorBuffer<C * sizeof(T)>::Size() / sizeof(T);
231 template <class T, TInt C>
232 const T& TVector<T, C>::operator[](TInt aIndex) const
234 const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::operator[](aIndex);
235 return *(reinterpret_cast<const T*>(ptr.Ptr()));