aboutsummaryrefslogtreecommitdiffstats
path: root/distrib/sdl-1.2.15/src/main/symbian/EKA2/vectorbuffer.h
diff options
context:
space:
mode:
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.h240
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
+
+