Mercurial > sdl-ios-xcode
comparison 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 |
comparison
equal
deleted
inserted
replaced
3974:42578e98a295 | 3975:e85e65aec22f |
---|---|
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 |