symbian-qemu-0.9.1-12/libsdl-trunk/src/main/symbian/EKA2/vectorbuffer.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     vectorbuffer.cpp
       
     3     yet another circle buffer
       
     4 
       
     5     Markus Mertama
       
     6 */
       
     7 
       
     8 #ifndef __VECTORBUFFER_H__
       
     9 #define __VECTORBUFFER_H__
       
    10 
       
    11 #include<e32std.h>
       
    12 #define VLOG(x)
       
    13 #define VECPANIC(x) VectorPanic(x, __LINE__)
       
    14 void VectorPanic(TInt, TInt);
       
    15 
       
    16 
       
    17 //int DEBUG_INT;
       
    18 
       
    19 NONSHARABLE_CLASS(TNodeBuffer)
       
    20     {
       
    21     public:
       
    22     protected:
       
    23         NONSHARABLE_CLASS(TNode)
       
    24             {
       
    25             public:
       
    26                 static  TNode* Empty(TUint8* iBuffer);
       
    27                 static  TNode* New(TNode* aPrev,  const TDesC8& aData);
       
    28                 const TUint8* Ptr() const;
       
    29                 TInt Size() const;
       
    30                 inline TNode* Succ();
       
    31                 static void SetSucc(TNode*& aNode);
       
    32                 void Terminator(TNode* aNode);
       
    33             private:
       
    34                 TNode* iSucc;
       
    35             };
       
    36     };
       
    37 
       
    38 inline TNodeBuffer::TNode* TNodeBuffer::TNode::Succ()
       
    39     {
       
    40     return iSucc;
       
    41     }
       
    42 
       
    43 template <TInt C>
       
    44 NONSHARABLE_CLASS(TVectorBuffer) : public TNodeBuffer
       
    45     {
       
    46     public:
       
    47         TVectorBuffer();
       
    48         TInt Append(const TDesC8& aData);
       
    49      //   TInt AppendOverwrite(const TDesC8& aData);
       
    50         TPtrC8 Shift();
       
    51         TPtrC8 operator[](TInt aIndex) const;
       
    52         TInt Size() const;
       
    53     private:
       
    54         TInt GetRoom(TInt aSize) const;
       
    55         TInt Unreserved() const;
       
    56     private:
       
    57         TNode* iTop;
       
    58         TNode* iBottom;
       
    59         TInt iSize;
       
    60         TUint8 iBuffer[C];
       
    61     };
       
    62 
       
    63 template <TInt C>
       
    64 TVectorBuffer<C>::TVectorBuffer() : iSize(0)
       
    65     {
       
    66     Mem::FillZ(iBuffer, C);
       
    67     iTop = TNode::Empty(iBuffer); //these points to buffer
       
    68     iBottom = TNode::Empty(iBuffer);
       
    69     }
       
    70 
       
    71 template<TInt C >
       
    72 TInt TVectorBuffer<C>::Unreserved() const
       
    73     {
       
    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 
       
    81                     
       
    82         const TInt room = C - bytesbetween - topsize; 
       
    83         return room;
       
    84         }
       
    85     if(bytesbetween == 0)           
       
    86         {
       
    87         
       
    88         if(Size() > 0)              
       
    89             return 0;               
       
    90         else
       
    91             return C - topsize;
       
    92         }
       
    93     const TInt room = -bytesbetween - topsize; //free is space between pointers
       
    94     return room;                     
       
    95     }
       
    96 
       
    97 template <TInt C>
       
    98 TInt TVectorBuffer<C>::GetRoom(TInt aSize) const
       
    99     {
       
   100     const TInt bytesnew = sizeof(TNode) + aSize;
       
   101     const TInt room = Unreserved() - bytesnew;
       
   102     return room;
       
   103     }
       
   104 
       
   105 template <TInt C>
       
   106 TInt TVectorBuffer<C>::Append(const TDesC8& aData) //ei ole ok!
       
   107     {
       
   108     const TInt len = aData.Length();
       
   109     if(GetRoom(len) < 0)
       
   110         {
       
   111         return KErrOverflow;
       
   112         }
       
   113     if(iBottom->Succ()->Ptr() - iBuffer > (C - (len + TInt(sizeof(TNode)))))
       
   114         {
       
   115         VLOG("rc");
       
   116        // RDebug::Print(_L("vector: append"));
       
   117         TNode* p = TNode::Empty(iBuffer);
       
   118         iBottom->Terminator(p);
       
   119       	iBottom = p;
       
   120       	return Append(aData);
       
   121      //	Append();
       
   122      //	iBottom = TNode::New(p, aData); //just append something into end
       
   123         } 
       
   124     
       
   125     //DEBUG_INT++;
       
   126          
       
   127     iBottom = TNode::New(iBottom, aData);
       
   128 
       
   129     iSize += len;
       
   130     return KErrNone;
       
   131     }
       
   132 
       
   133 /*
       
   134 template <TInt C>
       
   135 TInt TVectorBuffer<C>::AppendOverwrite(const TDesC8& aData) //ei ole ok!
       
   136     {
       
   137     while(Append(aData) == KErrOverflow)
       
   138         {
       
   139         if(iTop->Succ() == NULL)
       
   140             {
       
   141             return KErrUnderflow;
       
   142             }
       
   143         //Shift(); //data is lost
       
   144         }
       
   145     return KErrNone;
       
   146     }
       
   147 */
       
   148 template <TInt C>
       
   149 TPtrC8 TVectorBuffer<C>::Shift()
       
   150     {
       
   151     __ASSERT_ALWAYS(iTop->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
       
   152     TNode* node = iTop;
       
   153     iTop = iTop->Succ();
       
   154     if(iTop > node)
       
   155         {
       
   156       //  DEBUG_INT--;
       
   157         iSize -= node->Size();
       
   158         return TPtrC8(node->Ptr(), node->Size());
       
   159         }
       
   160     else
       
   161         {
       
   162       //  RDebug::Print(_L("vector: shift"));
       
   163         return Shift(); //this happens when buffer is terminated, and data lies in next 
       
   164         }
       
   165     }
       
   166 
       
   167 template <TInt C>
       
   168 TInt TVectorBuffer<C>::Size() const
       
   169     {
       
   170     return iSize;
       
   171     }
       
   172 
       
   173 template <TInt C>
       
   174 TPtrC8 TVectorBuffer<C>::operator[](TInt aIndex) const
       
   175     {
       
   176     TInt index = 0;
       
   177     TNode* t = iTop->Size() > 0 ? iTop : iTop->Succ(); //eliminate terminator
       
   178     while(index < aIndex)
       
   179         {
       
   180         TNode* nt = t->Succ();
       
   181         if(nt < t)
       
   182             {
       
   183             nt = nt->Succ();
       
   184             }
       
   185         t = nt;
       
   186         if(t->Size() > 0)
       
   187         	index++;
       
   188         __ASSERT_ALWAYS(t->Succ() != NULL, VECPANIC(KErrUnderflow)); //can never pass-by bottom
       
   189         }
       
   190     return t->Ptr();
       
   191     }
       
   192 
       
   193 
       
   194 template <class T, TInt C>
       
   195 NONSHARABLE_CLASS(TVector) : public TVectorBuffer<C * sizeof(T)>
       
   196     {
       
   197     public:
       
   198         TVector();
       
   199         TInt Append(const T& aData);
       
   200         const T& Shift();
       
   201         TInt Size() const;
       
   202         const T& operator[](TInt aIndex) const;
       
   203     };
       
   204 
       
   205 template <class T, TInt C>
       
   206 TVector<T, C>::TVector() : TVectorBuffer<C * sizeof(T)>()
       
   207     {
       
   208     }
       
   209 
       
   210 template <class T, TInt C>
       
   211 TInt TVector<T, C>::Append(const T& aData)
       
   212     {
       
   213     const TPckgC<T> data(aData);
       
   214     return TVectorBuffer<C * sizeof(T)>::Append(data);
       
   215     }
       
   216 
       
   217 template <class T, TInt C>
       
   218 const T& TVector<T, C>::Shift()
       
   219     {
       
   220     const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::Shift();
       
   221     return *(reinterpret_cast<const T*>(ptr.Ptr()));
       
   222     }
       
   223 
       
   224 
       
   225 template <class T, TInt C>
       
   226 TInt TVector<T, C>::Size() const
       
   227     {
       
   228     return TVectorBuffer<C * sizeof(T)>::Size() / sizeof(T);
       
   229     }
       
   230 
       
   231 template <class T, TInt C>
       
   232 const T& TVector<T, C>::operator[](TInt aIndex) const
       
   233     {
       
   234     const TPtrC8 ptr = TVectorBuffer<C * sizeof(T)>::operator[](aIndex);
       
   235     return *(reinterpret_cast<const T*>(ptr.Ptr()));
       
   236     }
       
   237 
       
   238 #endif
       
   239 
       
   240