|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Definition of the databuffer source reader active object class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDES |
|
20 #include "DataCopyEngineAO.h" |
|
21 #include "DataBufferDataSource.h" |
|
22 #include "SourceQueueItem.h" |
|
23 #include "SinkQueueItem.h" |
|
24 #include <e32cmn.h> |
|
25 |
|
26 #ifdef _DEBUG |
|
27 #define DEBPRN1(str) \ |
|
28 RDebug::Print(str); |
|
29 #define DEBPRN2(str, val1) \ |
|
30 RDebug::Print(str, val1); |
|
31 #define DEBPRN3(str, val1, val2) \ |
|
32 RDebug::Print(str, val1, val2); |
|
33 #define DEBPRN4(str, val1, val2, val3) \ |
|
34 RDebug::Print(str, val1, val2, val3); |
|
35 #define DEBPRN5(str, val1, val2, val3, val4) \ |
|
36 RDebug::Print(str, val1, val2, val3, val4); |
|
37 #else |
|
38 #define DEBPRN1(str) |
|
39 #define DEBPRN2(str, val1) |
|
40 #define DEBPRN3(str, val1, val2) |
|
41 #define DEBPRN4(str, val1, val2, val3) |
|
42 #define DEBPRN5(str, val1, val2, val3, val4) |
|
43 #endif // _DEBUG |
|
44 |
|
45 |
|
46 CDataCopyEngineAO::CDataCopyEngineAO( TSglQue<CSourceQueueItem>* aSourceQueue, |
|
47 TSglQue<CSinkQueueItem>* aSinkQueue, |
|
48 MDataCopyEngineObserver& aObserver ) |
|
49 : CActive( CActive::EPriorityStandard ), |
|
50 iSourceQueue( aSourceQueue ), |
|
51 iSinkQueue( aSinkQueue ), |
|
52 iObserver( &aObserver ) |
|
53 { |
|
54 CActiveScheduler::Add( this ); |
|
55 } |
|
56 |
|
57 CDataCopyEngineAO::~CDataCopyEngineAO() |
|
58 { |
|
59 Cancel(); |
|
60 delete iSrcDataDes; |
|
61 } |
|
62 |
|
63 CDataCopyEngineAO* CDataCopyEngineAO::NewL( TSglQue<CSourceQueueItem>* aSourceQueue, |
|
64 TSglQue<CSinkQueueItem>* aSinkQueue, |
|
65 MDataCopyEngineObserver& aObserver ) |
|
66 { |
|
67 CDataCopyEngineAO* self = new (ELeave) CDataCopyEngineAO( aSourceQueue, aSinkQueue, aObserver ); |
|
68 CleanupStack::PushL( self ); |
|
69 self->ConstructL(); |
|
70 CleanupStack::Pop( self ); |
|
71 return self; |
|
72 } |
|
73 |
|
74 void CDataCopyEngineAO::ConstructL() |
|
75 { |
|
76 // No impl yet |
|
77 } |
|
78 |
|
79 void CDataCopyEngineAO::SourceQueueChanged() |
|
80 { |
|
81 if (iState == EWaitingForSourceQueueSignal) |
|
82 { |
|
83 iState = EExecuting; |
|
84 KickSignal(); |
|
85 } |
|
86 } |
|
87 |
|
88 void CDataCopyEngineAO::SinkQueueChanged() |
|
89 { |
|
90 DEBPRN2(_L("CDataCopyEngineAO::SinkQueueChanged:State[%d]"), iState); |
|
91 if ( iState == EWaitingForSinkQueueSignal ) |
|
92 { |
|
93 iState = EExecuting; |
|
94 KickSignal(); |
|
95 } |
|
96 } |
|
97 |
|
98 void CDataCopyEngineAO::KickSignal() |
|
99 { |
|
100 if ( ( iState != EStopped ) && ( iState != EPaused ) && ( !IsActive() ) ) |
|
101 { |
|
102 TRequestStatus* s = &iStatus; |
|
103 SetActive(); |
|
104 User::RequestComplete( s, KErrNone ); |
|
105 } |
|
106 } |
|
107 |
|
108 void CDataCopyEngineAO::Start() |
|
109 { |
|
110 if ( iState == EStopped ) |
|
111 { |
|
112 iState = EExecuting; |
|
113 iSinkQueueItemProcessed = EFalse; |
|
114 iSourceQueueItemProcessed = EFalse; |
|
115 KickSignal(); |
|
116 } |
|
117 else if ( iState == EPaused ) |
|
118 { |
|
119 iState = EExecuting; |
|
120 KickSignal(); |
|
121 } |
|
122 } |
|
123 |
|
124 void CDataCopyEngineAO::Stop() |
|
125 { |
|
126 Cancel(); |
|
127 iState = EStopped; |
|
128 delete iSrcDataDes; |
|
129 iSrcDataDes = NULL; |
|
130 iSrcDataPos = 0; |
|
131 } |
|
132 |
|
133 void CDataCopyEngineAO::Pause() |
|
134 { |
|
135 Cancel(); |
|
136 iState = EPaused; |
|
137 } |
|
138 |
|
139 void CDataCopyEngineAO::RunL() |
|
140 { |
|
141 DEBPRN2(_L("CDataCopyEngineAO::RunL() State[%d]"),iState); |
|
142 |
|
143 if ( iState != EExecuting ) |
|
144 return; |
|
145 |
|
146 // If we are waiting for signalling sink queue item processed event, |
|
147 // notify the observer |
|
148 if ( iSourceQueueItemProcessed ) |
|
149 { |
|
150 iSourceQueueItemProcessed = EFalse; |
|
151 delete iSrcDataDes; |
|
152 iSrcDataDes = NULL; |
|
153 iSrcDataPos = 0; |
|
154 iObserver->SourceQueueItemProcessed(); |
|
155 KickSignal(); |
|
156 return; |
|
157 } |
|
158 |
|
159 // If we are waiting for signalling source queue item processed event, |
|
160 // notify the observer |
|
161 if ( iSinkQueueItemProcessed ) |
|
162 { |
|
163 iSinkQueueItemProcessed = EFalse; |
|
164 iObserver->SinkQueueItemProcessed(); |
|
165 KickSignal(); |
|
166 return; |
|
167 } |
|
168 |
|
169 // No request in the source queue |
|
170 if ( iSourceQueue->IsEmpty() ) |
|
171 { |
|
172 iState = EWaitingForSourceQueueSignal; |
|
173 return; |
|
174 } |
|
175 |
|
176 // No request in the sink queue |
|
177 if ( iSinkQueue->IsEmpty() ) |
|
178 { |
|
179 iState = EWaitingForSinkQueueSignal; |
|
180 return; |
|
181 } |
|
182 |
|
183 CSourceQueueItem* srcItem = iSourceQueue->First(); |
|
184 CSinkQueueItem* snkItem = iSinkQueue->First(); |
|
185 // If there is no data copied into local buffer |
|
186 if ( !iSrcDataDes ) |
|
187 { |
|
188 // If data from source item can fit into dest buffer |
|
189 // copy directly |
|
190 |
|
191 if ( srcItem->DataSize() <= ( snkItem->Buffer()->Data().MaxLength() - snkItem->Buffer()->Data().Length() ) ) |
|
192 { |
|
193 // Create a temp ptr pointing to buffer in the sink queue |
|
194 TPtr8 ptr( ( const_cast<TUint8*>( ( snkItem->Buffer()->Data().Ptr() ) ) + snkItem->Buffer()->Data().Length() ), |
|
195 0, |
|
196 ( snkItem->Buffer()->Data().MaxLength() - snkItem->Buffer()->Data().Length() ) ); |
|
197 // Read data into the buffer |
|
198 srcItem->ReadData( ptr ); |
|
199 |
|
200 // Update descriptor attribute and position attribute |
|
201 snkItem->Buffer()->Data().SetLength( snkItem->Buffer()->Data().Length() + srcItem->DataSize() ); |
|
202 |
|
203 // Now that data is copied from source queue item, signal it is done |
|
204 iSourceQueueItemProcessed = ETrue; |
|
205 // If src queue item is last buffer signal sink buffer |
|
206 if ( srcItem->IsLastBuffer() ) |
|
207 { |
|
208 snkItem->Buffer()->SetLastBuffer( ETrue ); |
|
209 iSinkQueueItemProcessed = ETrue; |
|
210 } |
|
211 else if ( snkItem->Buffer()->Data().Length() == snkItem->Buffer()->Data().MaxLength() ) |
|
212 { |
|
213 snkItem->Buffer()->SetLastBuffer( EFalse ); |
|
214 iSinkQueueItemProcessed = ETrue; |
|
215 } |
|
216 |
|
217 /* |
|
218 if ( iSinkQueueItemProcessed ) |
|
219 { |
|
220 TUint8* bufPtr = const_cast<TUint8*>(snkItem->Buffer()->Data().Ptr()); |
|
221 if ( snkItem->Buffer()->Data().Length() > 5 ) |
|
222 { |
|
223 RDebug::Print(_L("CDataCopyEngineAO::RunL 1 data[0x%x][0x%x][0x%x][0x%x][0x%x]"), \ |
|
224 *bufPtr,*(bufPtr+1),*(bufPtr+2),*(bufPtr+3),*(bufPtr+4)); |
|
225 } |
|
226 } |
|
227 */ |
|
228 |
|
229 |
|
230 // Continue |
|
231 KickSignal(); |
|
232 return; |
|
233 } |
|
234 else // if (srcItem->DataSize() <= |
|
235 { |
|
236 // The data in the source queue item is larger than what |
|
237 // destination can hold. So copy data to local buffer |
|
238 iSrcDataDes = HBufC8::NewL(srcItem->DataSize()); |
|
239 TPtr8 ptr = iSrcDataDes->Des(); |
|
240 srcItem->ReadData(ptr); |
|
241 iSrcDataPos = 0; |
|
242 } |
|
243 } |
|
244 // Now we have data copied over to temp buffer |
|
245 TInt copySize = Min( ( iSrcDataDes->Des().Length() - iSrcDataPos), |
|
246 ( snkItem->Buffer()->Data().MaxLength() - snkItem->Buffer()->Data().Length() ) ); |
|
247 // Copy data from source to destination queue item |
|
248 snkItem->Buffer()->Data().Append( ( iSrcDataDes->Des().Ptr() + iSrcDataPos ), |
|
249 copySize ); |
|
250 // Update the source position. |
|
251 iSrcDataPos += copySize; |
|
252 // Update the position in destination queue item. |
|
253 //snkItem->Buffer()->SetPosition( snkItem->Buffer()->Position() + copySize ); |
|
254 |
|
255 if ( iSrcDataPos == iSrcDataDes->Des().Length() ) |
|
256 { |
|
257 iSourceQueueItemProcessed = ETrue; |
|
258 } |
|
259 // If src queue item is last buffer signal sink buffer |
|
260 if ( srcItem->IsLastBuffer() && (iSrcDataPos == iSrcDataDes->Des().Length()) ) |
|
261 { |
|
262 snkItem->Buffer()->SetLastBuffer( ETrue ); |
|
263 iSinkQueueItemProcessed = ETrue; |
|
264 } |
|
265 else if ( snkItem->Buffer()->Data().Length() == snkItem->Buffer()->Data().MaxLength() ) |
|
266 { |
|
267 snkItem->Buffer()->SetLastBuffer( EFalse ); |
|
268 iSinkQueueItemProcessed = ETrue; |
|
269 } |
|
270 |
|
271 /* |
|
272 if ( iSinkQueueItemProcessed ) |
|
273 { |
|
274 TUint8* bufPtr = const_cast<TUint8*>(snkItem->Buffer()->Data().Ptr()); |
|
275 if ( snkItem->Buffer()->Data().Length() > 5 ) |
|
276 { |
|
277 RDebug::Print(_L("CDataCopyEngineAO::RunL 2 data[0x%x][0x%x][0x%x][0x%x][0x%x]"), \ |
|
278 *bufPtr,*(bufPtr+1),*(bufPtr+2),*(bufPtr+3),*(bufPtr+4)); |
|
279 } |
|
280 } |
|
281 */ |
|
282 |
|
283 // Continue |
|
284 KickSignal(); |
|
285 return; |
|
286 |
|
287 } |
|
288 |
|
289 void CDataCopyEngineAO::DoCancel() |
|
290 { |
|
291 } |
|
292 |
|
293 TInt CDataCopyEngineAO::RunError(TInt /*aError*/) |
|
294 { |
|
295 // FIX LATER Panic client |
|
296 return KErrNone; |
|
297 } |
|
298 |
|
299 // End of File |