diff src/main/symbian/EKA2/vectorbuffer.h @ 3975:e85e65aec22f SDL-1.2

Added S60 port.
author Ryan C. Gordon <icculus@icculus.org>
date Sun, 24 Jun 2007 18:26:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/symbian/EKA2/vectorbuffer.h	Sun Jun 24 18:26:35 2007 +0000
@@ -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
+
+