diff options
Diffstat (limited to 'distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h')
-rw-r--r-- | distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h b/distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h new file mode 100644 index 0000000..3d8be58 --- /dev/null +++ b/distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h @@ -0,0 +1,240 @@ +/* + vectorbuffer.cpp + yet another circle buffer + + Markus Mertama +*/ + +#ifndef __VECTORBUFFER_H__ +#define __VECTORBUFFER_H__ + +#include<e32std.h> +#define VLOG(x) +#define VECPANIC(x) VectorPanic(x, __LINE__) +void VectorPanic(TInt, TInt); + + +//int DEBUG_INT; + +NONSHARABLE_CLASS(TNodeBuffer) + { + public: + protected: + NONSHARABLE_CLASS(TNode) + { + public: + static TNode* Empty(TUint8* iBuffer); + static TNode* New(TNode* aPrev, const TDesC8& aData); + const TUint8* Ptr() const; + TInt Size() const; + inline TNode* Succ(); + static void SetSucc(TNode*& aNode); + void Terminator(TNode* aNode); + private: + TNode* iSucc; + }; + }; + +inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ() + { + return iSucc; + } + +template <TInt C> +NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer + { + public: + TVectorBuffer(); + TInt Append(const TDesC8& aData); + // TInt AppendOverwrite(const TDesC8& aData); + TPtrC8 Shift(); + TPtrC8 operator[](TInt aIndex) const; + TInt Size() const; + private: + TInt GetRoom(TInt aSize) const; + TInt Unreserved() const; + private: + TNode* iTop; + TNode* iBottom; + TInt iSize; + TUint8 iBuffer[C]; + }; + +template <TInt C> +TVectorBuffer<C>::TVectorBuffer() : iSize(0) + { + Mem::FillZ(iBuffer, C); + iTop = TNode::Empty(iBuffer); //these points to buffer + iBottom = TNode::Empty(iBuffer); + } + +template<TInt C > +TInt TVectorBuffer<C>::Unreserved() const + { + __ASSERT_DEBUG(iBottom < iBottom->Succ(), VECPANIC(KErrCorrupt)); + const TInt bytesbetween = + reinterpret_cast<const TUint8*>(iBottom->Succ()) - + reinterpret_cast<const TUint8*>(iTop); + const TInt topsize = sizeof(TNode); + if(bytesbetween > 0) //bytesbetween is room between bottom and top + { //therefore free room is subracted from free space + + const TInt room = C - bytesbetween - topsize; + return room; + } + if(bytesbetween == 0) + { + + if(Size() > 0) + return 0; + else + return C - topsize; + } + const TInt room = -bytesbetween - topsize; //free is space between pointers + return room; + } + +template <TInt C> +TInt TVectorBuffer<C>::GetRoom(TInt aSize) const + { + const TInt bytesnew = sizeof(TNode) + aSize; + const TInt room = Unreserved() - bytesnew; + return room; + } + +template <TInt C> +TInt TVectorBuffer<C>::Append(const TDesC8& aData) //ei ole ok! + { + const TInt len = aData.Length(); + if(GetRoom(len) < 0) + { + return KErrOverflow; + } + if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode))))) + { + VLOG("rc"); + // RDebug::Print(_L("vector: append")); + TNode* p = TNode::Empty(iBuffer); + iBottom->Terminator(p); + iBottom = p; + return Append(aData); + // Append(); + // iBottom = TNode::New(p, aData); //just append something into end + } + + //DEBUG_INT++; + + iBottom = TNode::New(iBottom, aData); + + iSize += len; + return KErrNone; + } + +/* +template <TInt C> +TInt TVectorBuffer<C>::AppendOverwrite(const TDesC8& aData) //ei ole ok! + { + while(Append(aData) == KErrOverflow) + { + if(iTop->Succ() == NULL) + { + return KErrUnderflow; + } + //Shift(); //data is lost + } + return KErrNone; + } +*/ +template <TInt C> +TPtrC8 TVectorBuffer<C>::Shift() + { + __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + TNode* node = iTop; + iTop = iTop->Succ(); + if(iTop > node) + { + // DEBUG_INT--; + iSize -= node->Size(); + return TPtrC8(node->Ptr(), node->Size()); + } + else + { + // RDebug::Print(_L("vector: shift")); + return Shift(); //this happens when buffer is terminated, and data lies in next + } + } + +template <TInt C> +TInt TVectorBuffer<C>::Size() const + { + return iSize; + } + +template <TInt C> +TPtrC8 TVectorBuffer<C>::operator[](TInt aIndex) const + { + TInt index = 0; + TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator + while(index < aIndex) + { + TNode* nt = t->Succ(); + if(nt < t) + { + nt = nt->Succ(); + } + t = nt; + if(t->Size() > 0) + index++; + __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom + } + return t->Ptr(); + } + + +template <class T, TInt C> +NONSHARABLE_CLASS(TVector) : public TVectorBuffer<C * sizeof(T)> + { + public: + TVector(); + TInt Append(const T& aData); + const T& Shift(); + TInt Size() const; + const T& operator[](TInt aIndex) const; + }; + +template <class T, TInt C> +TVector<T, C>::TVector() : TVectorBuffer<C * sizeof(T)>() + { + } + +template <class T, TInt C> +TInt TVector<T, C>::Append(const T& aData) + { + const TPckgC<T> data(aData); + return TVectorBuffer<C * sizeof(T)>::Append(data); + } + +template <class T, TInt C> +const T& TVector<T, C>::Shift() + { + const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::Shift(); + return *(reinterpret_cast<const T*>(ptr.Ptr())); + } + + +template <class T, TInt C> +TInt TVector<T, C>::Size() const + { + return TVectorBuffer<C * sizeof(T)>::Size() / sizeof(T); + } + +template <class T, TInt C> +const T& TVector<T, C>::operator[](TInt aIndex) const + { + const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::operator[](aIndex); + return *(reinterpret_cast<const T*>(ptr.Ptr())); + } + +#endif + + |