Update contrib.
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include "metadatafilewriter.h"
32 const TInt KMetaDataWriterBufferSize = (4*4096);
33 const TInt KMetaDataWriterInputBufCount = 10;
34 const TInt KMetaDataWriterOutputBufCount = 4;
36 // ============================ MEMBER FUNCTIONS ===============================
38 CMetaDataWriterBuffer::~CMetaDataWriterBuffer()
43 // -----------------------------------------------------------------------------
44 // CMetaDataFileWriter::CMetaDataFileWriter
45 // C++ default constructor can NOT contain any code, that
47 // -----------------------------------------------------------------------------
49 CMetaDataFileWriter::CMetaDataFileWriter() : CActive( EPriorityHigh )
53 // -----------------------------------------------------------------------------
54 // CMetaDataFileWriter::ConstructL
55 // Symbian 2nd phase constructor can leave.
56 // -----------------------------------------------------------------------------
58 void CMetaDataFileWriter::ConstructL( )
60 PRINT(_L("CMetaDataFileWriter::ConstructL() in"));
63 iAsyncWritingOngoing = EFalse;
67 for (TInt i=0; i<KMetaDataWriterInputBufCount; i++)
69 iOutputFile.AppendL(NULL);
71 CMetaDataWriterBuffer* emptyInputBuffer = new (ELeave) CMetaDataWriterBuffer;
72 CleanupStack::PushL(emptyInputBuffer);
74 emptyInputBuffer->iData = HBufC8::NewL(KMetaDataWriterBufferSize);
75 emptyInputBuffer->iOutputFileNum = i;
76 iInputBufferArray.AppendL(emptyInputBuffer);
78 CleanupStack::Pop(emptyInputBuffer);
80 iInputBufferArrayDelivered[i] = 0;
83 for (TInt j=0; j<KMetaDataWriterOutputBufCount; j++)
85 CMetaDataWriterBuffer* emptyOutputBuffer = new (ELeave) CMetaDataWriterBuffer;
86 CleanupStack::PushL(emptyOutputBuffer);
88 emptyOutputBuffer->iData = HBufC8::NewL(KMetaDataWriterBufferSize);
89 emptyOutputBuffer->iOutputFileNum = -1;
90 iEmptyBufferQueue.AppendL(emptyOutputBuffer);
92 CleanupStack::Pop(emptyOutputBuffer);
95 CActiveScheduler::Add(this);
97 PRINT(_L("CMetaDataFileWriter::ConstructL() out"));
100 // -----------------------------------------------------------------------------
101 // CMetaDataFileWriter::NewL
102 // Two-phased constructor.
103 // -----------------------------------------------------------------------------
105 CMetaDataFileWriter* CMetaDataFileWriter::NewL()
107 PRINT(_L("CMetaDataFileWriter::NewL() in"));
109 CMetaDataFileWriter* self = new(ELeave) CMetaDataFileWriter;
110 CleanupStack::PushL(self);
112 CleanupStack::Pop(self);
114 PRINT(_L("CMetaDataFileWriter::NewL() out"));
120 CMetaDataFileWriter::~CMetaDataFileWriter()
122 PRINT(_L("CMetaDataFileWriter::~CMetaDataFileWriter() in"));
127 if ( iAsyncWritingOngoing )
133 TRequestStatus* status = &iStatus;
134 User::RequestComplete( status, KErrNone );
140 iInputBufferArray.ResetAndDestroy();
141 iOutputBufferQueue.ResetAndDestroy();
142 iEmptyBufferQueue.ResetAndDestroy();
143 PRINT(_L("CMetaDataFileWriter::~CMetaDataFileWriter() out"));
146 // -----------------------------------------------------------------------------
147 // CMetaDataFileWriter::Write( const TDesC8& aBuf )
148 // Writes incoming buffer data to internal buffers for writing to disk.
149 // (other items were commented in a header).
150 // -----------------------------------------------------------------------------
152 TInt CMetaDataFileWriter:: Write( RFile64& aFile, const TInt aFileNumber, const TDesC8& aBuf )
154 PRINT(_L("CMetaDataFileWriter::Write() in"));
155 PRINT((_L("e_cmetadatawriter_write 1")));
157 iOutputFile[aFileNumber] = &aFile;
159 PRINT((_L("e_cmetadatawriter_write_adddatatobuffer 1")));
160 TInt error = AddDataToBuffer( aFileNumber, aBuf );
161 if ( error != KErrNone )
163 PRINT((_L("CMetaDataFileWriter::Write() buffer write error: %d"), error));
166 PRINT((_L("e_cmetadatawriter_write_adddatatobuffer 0")));
168 PRINT((_L("CMetaDataFileWriter::Write() Write Buffer, Status: Full:%d Empty:%d "),
169 iOutputBufferQueue.Count(), iEmptyBufferQueue.Count() ));
171 if ( iAsyncWritingOngoing )
173 if ( iOutputBufferQueue.Count() >= KFileWriterHardBufLimit )
175 PRINT((_L("CMetaDataFileWriter::Write() Waiting async write to complete")));
176 PRINT((_L("e_cmetadatawriter_write_waitasync 1")));
177 User::WaitForRequest( iStatus );
178 PRINT((_L("e_cmetadatawriter_write_waitasync 0")));
179 PRINT((_L("CMetaDataFileWriter::Write() Async write done")));
181 if (error != KErrNone)
183 PRINT((_L("CMetaDataFileWriter::Write() runL leave, error: %d"), error));
190 if ( iOutputBufferQueue.Count() )
192 PRINT(_L("CMetaDataFileWriter::Write() writing async"));
194 PRINT((_L("e_cmetadatawriter_write_startwrite 1")));
196 iOutputFile[iOutputBufferQueue[0]->iOutputFileNum]->Write( *(iOutputBufferQueue[0]->iData), iStatus );
197 PRINT((_L("e_cmetadatawriter_write_startwrite 0")));
198 iAsyncWritingOngoing = ETrue;
206 PRINT(_L("CMetaDataFileWriter::Write() out"));
207 PRINT((_L("e_cmetadatawriter_write 0")));
211 // -----------------------------------------------------------------------------
212 // CMetaDataFileWriter::Flush( )
213 // Flush internal buffers to disk.
214 // (other items were commented in a header).
215 // -----------------------------------------------------------------------------
217 TInt CMetaDataFileWriter::Flush( )
219 PRINT(_L("CMetaDataFileWriter::Flush() in"));
220 PRINT((_L("e_cmetadatawriter_flush 1")));
221 PRINT((_L("CMetaDataFileWriter::Flush() FullCount: %d "), iOutputBufferQueue.Count()));
223 TInt error = KErrNone;
226 if ( iAsyncWritingOngoing )
228 PRINT((_L("CMetaDataFileWriter::Flush() Waiting async write to complete")));
229 PRINT((_L("e_cmetadatawriter_flush_waitasyncstop 1")));
230 User::WaitForRequest( iStatus );
231 PRINT((_L("e_cmetadatawriter_flush_waitasyncstop 0")));
232 PRINT((_L("CMetaDataFileWriter::Flush() Async write done, flushing")));
234 if (error != KErrNone)
236 PRINT((_L("CMetaDataFileWriter::Flush() call runL leave, error: %d"), error));
241 while ( iOutputBufferQueue.Count() )
243 PRINT((_L("e_cmetadatawriter_flush_writesync 1")));
245 error = iOutputFile[iOutputBufferQueue[0]->iOutputFileNum]->Write( *(iOutputBufferQueue[0]->iData) );
246 if ( error == KErrNone )
248 error = iEmptyBufferQueue.Append(iOutputBufferQueue[0]);
249 if (error == KErrNone)
251 iOutputBufferQueue[0]->iData->Des().Zero();
252 iOutputBufferQueue[0]->iOutputFileNum = -1;
253 iOutputBufferQueue.Remove(0);
257 PRINT((_L("CMetaDataFileWriter::Flush() iEmptyBufferQueue.Append failed, error: %d"), error));
263 PRINT((_L("CMetaDataFileWriter::Flush() fullBufQueue write failed, error: %d"), error));
267 PRINT((_L("e_cmetadatawriter_flush_writesync 0")));
270 if ( !iFlushDone ) // Flush only once
273 for ( TInt i=0; i < KMetaDataWriterInputBufCount; i++ )
275 if ( iOutputFile[i] )
277 PRINT((_L("e_cmetadatawriter_flush_write_tempfiles 1")));
278 error = iOutputFile[i]->Flush();
279 PRINT((_L("e_cmetadatawriter_flush_write_tempfiles 0")));
280 PRINT((_L("CMetaDataFileWriter::Flush() inputbuf[%d] flush return code: %d"), i, error));
286 PRINT((_L("CMetaDataFileWriter::Flush() FullCount: %d <= Should be 0"), iOutputBufferQueue.Count()));
287 PRINT(_L("CMetaDataFileWriter::Flush() out"));
288 PRINT((_L("e_cmetadatawriter_flush 0")));
292 // -----------------------------------------------------------------------------
293 // CMetaDataFileWriter::AddDataToBuffer( const TDesC8& aBuf )
294 // Writes incoming data to internal buffers and buffer queues..
295 // (other items were commented in a header).
296 // -----------------------------------------------------------------------------
298 TInt CMetaDataFileWriter::AddDataToBuffer(const TInt aFileNumber, const TDesC8& aBuf )
300 PRINT(_L("CMetaDataFileWriter::AddDataToBuffer() in"));
302 TInt byteswritten = 0;
304 TInt available = 0; // Available bytes in write buffer
305 TInt error = KErrNone;
307 HBufC8* inputBuf = iInputBufferArray[aFileNumber]->iData;
309 if ( iError != KErrNone )
311 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer() out, RunL iError: %d"), iError));
315 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer() Save Buffer, Size: %d "), aBuf.Length() ));
317 while (byteswritten < aBuf.Length() )
319 available = (inputBuf->Des()).MaxLength() - inputBuf->Length();
323 numbytes = aBuf.Length() - byteswritten;
324 if (numbytes > available)
326 numbytes = available;
328 inputBuf->Des().Append( aBuf.Mid( byteswritten, numbytes ) );
329 byteswritten += numbytes;
331 else // Buffer is full, move it to outputqueue and use empty/new buf as input.
333 if ( iEmptyBufferQueue.Count() == 0 )
335 CMetaDataWriterBuffer* emptyInputBuffer = 0;
337 emptyInputBuffer = new CMetaDataWriterBuffer;
338 if ( !emptyInputBuffer )
340 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer(), memory alloc failed")));
341 iError = KErrNoMemory;
345 TRAP(error, emptyInputBuffer->iData = HBufC8::NewL( KMetaDataWriterBufferSize ));
346 if ( error != KErrNone )
348 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer(), memory alloc failed: %d"), error));
349 delete emptyInputBuffer;
350 emptyInputBuffer = NULL;
356 error = iOutputBufferQueue.Append(iInputBufferArray[aFileNumber]);
357 if (error != KErrNone)
359 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer(), memory alloc failed: %d"), error));
360 delete emptyInputBuffer;
361 emptyInputBuffer = NULL;
366 // old full buffer to output queue.
367 emptyInputBuffer->iOutputFileNum = aFileNumber;
369 // new buffer to input.
370 iInputBufferArray[aFileNumber] = emptyInputBuffer;
375 // old full buffer to output queue.
376 TInt err = iOutputBufferQueue.Append( iInputBufferArray[aFileNumber] );
379 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer(), iOutputBufferQueue.Append failed: %d"), err));
384 // empty buffer from empty queue to input.
385 iInputBufferArray[aFileNumber] = iEmptyBufferQueue[0];
386 iInputBufferArray[aFileNumber]->iData->Des().Zero();
387 iInputBufferArray[aFileNumber]->iOutputFileNum = aFileNumber;
388 iEmptyBufferQueue.Remove(0);
391 inputBuf = iInputBufferArray[aFileNumber]->iData;
395 PRINT((_L("CMetaDataFileWriter::AddDataToBuffer() out, error: %d"), error));
399 // -----------------------------------------------------------------------------
400 // CMetaDataFileWriter::DoCancel()
401 // From CActive Cancels async request.
402 // -----------------------------------------------------------------------------
404 void CMetaDataFileWriter::DoCancel()
408 // -----------------------------------------------------------------------------
409 // CMetaDataFileWriter::RunL()
410 // From CActive Called when async request completes.
411 // -----------------------------------------------------------------------------
413 void CMetaDataFileWriter::RunL()
415 PRINT(_L("CMetaDataFileWriter::RunL() in"));
416 PRINT((_L("e_cmetadatawriter_runl 1")));
417 iAsyncWritingOngoing = EFalse;
419 if ( iStatus == KErrNone )
421 iEmptyBufferQueue.AppendL( iOutputBufferQueue[0] );
422 iOutputBufferQueue[0]->iData->Des().Zero();
423 iOutputBufferQueue[0]->iOutputFileNum = -1;
424 iOutputBufferQueue.Remove( 0 );
428 PRINT((_L("CMetaDataFileWriter::RunL() Write error in previous async: %d "), iStatus.Int() ));
429 iError = iStatus.Int();
433 PRINT((_L("CMetaDataFileWriter::RunL() Buffer written, Status: Full:%d Empty:%d "), iOutputBufferQueue.Count(), iEmptyBufferQueue.Count() ));
437 PRINT(_L("CMetaDataFileWriter::RunL() out, flushing"));
438 PRINT((_L("e_cmetadatawriter_runl 0")));
442 if ( iOutputBufferQueue.Count() >= KFileWriterHardBufLimit )
444 while ( iOutputBufferQueue.Count() > KFileWriterSoftBufLimit )
446 PRINT((_L("e_cmetadatawriter_runl1_write 1")));
447 iError = iOutputFile[iOutputBufferQueue[0]->iOutputFileNum]->Write( *(iOutputBufferQueue[0]->iData));
448 PRINT((_L("e_cmetadatawriter_runl1_write 0")));
449 if ( iError == KErrNone )
451 iEmptyBufferQueue.AppendL( iOutputBufferQueue[0] );
452 iOutputBufferQueue[0]->iData->Des().Zero();
453 iOutputBufferQueue[0]->iOutputFileNum = -1;
454 iOutputBufferQueue.Remove( 0 );
458 PRINT((_L("CMetaDataFileWriter::RunL() Write error: %d "), iError));
464 if ( iOutputBufferQueue.Count() >= KFileWriterSoftBufLimit )
466 PRINT((_L("e_cmetadatawriter_runl2_write 1")));
467 iError = iOutputFile[iOutputBufferQueue[0]->iOutputFileNum]->Write( *(iOutputBufferQueue[0]->iData));
468 PRINT((_L("e_cmetadatawriter_runl2_write 0")));
469 if ( iError == KErrNone )
471 iEmptyBufferQueue.AppendL( iOutputBufferQueue[0] );
472 iOutputBufferQueue[0]->iData->Des().Zero();
473 iOutputBufferQueue[0]->iOutputFileNum = -1;
474 iOutputBufferQueue.Remove( 0 );
478 PRINT((_L("CMetaDataFileWriter::RunL() Write error: %d "), iError));
483 if ( iOutputBufferQueue.Count() )
485 PRINT((_L("e_cmetadatawriter_runl3_write 1")));
486 iOutputFile[iOutputBufferQueue[0]->iOutputFileNum]->Write( *(iOutputBufferQueue[0]->iData), iStatus );
487 PRINT((_L("e_cmetadatawriter_runl3_write 0")));
488 iAsyncWritingOngoing = ETrue;
495 PRINT((_L("e_cmetadatawriter_runl 0")));
496 PRINT(_L("CMetaDataFileWriter::RunL() out"));
499 // -----------------------------------------------------------------------------
500 // CMetaDataFileWriter::RunError
501 // -----------------------------------------------------------------------------
503 TInt CMetaDataFileWriter::RunError(TInt aError)
510 // -----------------------------------------------------------------------------
511 // CMetaDataFileWriter::ReadBuffer
512 // -----------------------------------------------------------------------------
514 TInt CMetaDataFileWriter::ReadBuffer( const TInt aFileNumber, TDes8& aBuf, TInt bytestoread )
516 PRINT(_L("CMetaDataFileWriter::ReadBuffer() in"));
517 PRINT((_L("e_cmetadatawriter_readbuffer 1")));
520 PRINT((_L("CMetaDataFileWriter::ReadBuffer() iInputBufferArray[%d]->iData->Length(): %d, requested %d"), aFileNumber, iInputBufferArray[aFileNumber]->iData->Length(), bytestoread));
521 if ( !iInputBufferArray[aFileNumber]->iData->Length() )
525 else if ( (iInputBufferArray[aFileNumber]->iData->Length() -
526 iInputBufferArrayDelivered[aFileNumber]) >= bytestoread )
528 bytesread = bytestoread;
529 aBuf.Append( iInputBufferArray[aFileNumber]->iData->Mid( iInputBufferArrayDelivered[aFileNumber], bytesread ) );
530 iInputBufferArrayDelivered[aFileNumber] += bytesread;
532 // If the buffer is read empty, release it
533 if ( iInputBufferArray[aFileNumber]->iData->Length() == iInputBufferArrayDelivered[aFileNumber] )
535 PRINT((_L("CMetaDataFileWriter::ReadBuffer() iInputBufferArray[%d] %d delivered"), aFileNumber, iInputBufferArray[aFileNumber]->iData->Length()));
536 iInputBufferArray[aFileNumber]->iData->Des().Zero();
541 bytesread = iInputBufferArray[aFileNumber]->iData->Length() - iInputBufferArrayDelivered[aFileNumber];
542 aBuf.Append( iInputBufferArray[aFileNumber]->iData->Mid( iInputBufferArrayDelivered[aFileNumber], bytesread ) );
543 iInputBufferArrayDelivered[aFileNumber] += bytesread;
545 PRINT((_L("CMetaDataFileWriter::ReadBuffer() iInputBufferArray[%d] %d bytes delivered"), aFileNumber, iInputBufferArray[aFileNumber]->iData->Length()));
546 iInputBufferArray[aFileNumber]->iData->Des().Zero();
549 PRINT((_L("e_cmetadatawriter_readbuffer 0")));
550 PRINT(_L("CMetaDataFileWriter::ReadBuffer() out"));
552 return ( bytesread );