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 "filewriter.h"
27 //#define PRINT(x) RDebug::Print x
33 // ============================ MEMBER FUNCTIONS ===============================
35 // -----------------------------------------------------------------------------
36 // CFileWriter::CFileWriter
37 // C++ default constructor can NOT contain any code, that
39 // -----------------------------------------------------------------------------
41 CFileWriter::CFileWriter( TInt aInitSetSize, TInt aOutputBufferSizeSmall, TInt aOutputBufferSizeLarge ):
42 CActive( EPriorityHigh ),
43 iSetSize( aInitSetSize ),
44 iOutputBufferSizeSmall( aOutputBufferSizeSmall ),
45 iOutputBufferSizeLarge( aOutputBufferSizeLarge )
49 // -----------------------------------------------------------------------------
50 // CFileWriter::ConstructL
51 // Symbian 2nd phase constructor can leave.
52 // -----------------------------------------------------------------------------
54 void CFileWriter::ConstructL( RFile64& aFile )
56 PRINT((_L("CFileWriter::ConstructL() in")));
61 iWritingStarted = EFalse;
62 iOutputBufferSize = KFileWriterBufferSizeSmall;
63 iMaxOutputBufHardLimit = KFileWriterHardBufLimit;
64 iMaxOutputBufSoftLimit = KFileWriterSoftBufLimit;
66 iMemReadyForWriting = EFalse;
68 iEmptyBufferQueue.Reset();
69 iFullBufferQueue.Reset();
72 CActiveScheduler::Add(this);
73 PRINT((_L("CFileWriter::ConstructL() out")));
76 // -----------------------------------------------------------------------------
78 // Two-phased constructor.
79 // -----------------------------------------------------------------------------
81 CFileWriter* CFileWriter::NewL( RFile64& aFile, TInt aInitSetSize, TInt aOutputBufferSizeSmall, TInt aOutputBufferSizeLarge )
83 CFileWriter* self = new(ELeave) CFileWriter( aInitSetSize, aOutputBufferSizeSmall, aOutputBufferSizeLarge );
84 CleanupStack::PushL(self);
85 self->ConstructL( aFile );
86 CleanupStack::Pop(self);
92 CFileWriter::~CFileWriter()
94 PRINT((_L("CFileWriter::~CFileWriter() in")));
97 if ( iAsyncWritingOngoing )
103 TRequestStatus* status = &iStatus;
104 User::RequestComplete( status, KErrNone );
114 iEmptyBufferQueue.ResetAndDestroy();
115 iFullBufferQueue.ResetAndDestroy();
116 PRINT((_L("CFileWriter::~CFileWriter() out")));
119 // -----------------------------------------------------------------------------
120 // CFileWriter::UpdateOutputFileSize()
121 // Updates output file size and reserves extra space for following writing
122 // if iSetSize is set.
123 // Takes into account if the position in the file was changed.
124 // -----------------------------------------------------------------------------
126 void CFileWriter::UpdateOutputFileSize()
129 PRINT((_L("e_cfilewriter_write_updateoutputfilesize_seek 1")));
130 iOutputFile->Seek(ESeekCurrent, pos);
131 PRINT((_L("e_cfilewriter_write_updateoutputfilesize_seek 0")));
133 PRINT((_L("CFileWriter::UpdateOutputFileSize() pos: %Ld"), pos));
134 PRINT((_L("CFileWriter::UpdateOutputFileSize() iOutputFileSize: %Ld"), iOutputFileSize));
135 PRINT((_L("CFileWriter::UpdateOutputFileSize() iSetSize: %Ld"), iSetSize));
137 if (pos > iOutputFileSize)
139 iOutputFileSize = pos;
142 while (iOutputFileSize >= iSetSize)
144 iSetSize += static_cast<TInt64>(iOutputBufferSize) * (static_cast<TInt64>(iMaxOutputBufHardLimit) >> 1);
145 PRINT((_L("e_cfilewriter_updateoutputfilesize_setsize 1")));
146 iOutputFile->SetSize( iSetSize );
147 PRINT((_L("e_cfilewriter_updateoutputfilesize_setsize 0")));
151 // -----------------------------------------------------------------------------
152 // CFileWriter::Write( const TDesC8& aBuf )
153 // Writes incoming buffer data to internal buffers for writing to disk.
154 // (other items were commented in a header).
155 // -----------------------------------------------------------------------------
157 TInt CFileWriter::Write( const TDesC8& aBuf )
159 PRINT(_L("CFileWriter::Write() in"));
160 PRINT((_L("e_cfilewriter_write 1")));
162 iWritingStarted = ETrue;
164 if ( !iMemReadyForWriting )
169 PRINT((_L("e_cfilewriter_write_adddatatobuffer 1")));
170 TInt error = AddDataToBuffer( aBuf );
171 PRINT((_L("e_cfilewriter_write_adddatatobuffer 0")));
173 if ( error != KErrNone )
175 PRINT((_L("CFileWriter::Write() buffer write error: %d"), error));
179 PRINT((_L("CFileWriter::Write() Write Buffer, Status: Full:%d Empty:%d "),
180 iFullBufferQueue.Count(), iEmptyBufferQueue.Count() ));
182 if ( iAsyncWritingOngoing )
184 if ( iFullBufferQueue.Count() >= iMaxOutputBufHardLimit )
186 PRINT((_L("CFileWriter::Write() Waiting async write to complete")));
187 PRINT((_L("e_cfilewriter_write_wait_async 1")));
188 User::WaitForRequest( iStatus );
189 PRINT((_L("e_cfilewriter_write_wait_async 0")));
190 PRINT((_L("CFileWriter::Write() Async write done")));
192 if (error != KErrNone)
194 PRINT((_L("CFileWriter::Write() call runL leave, error: %d"), error));
201 if ( iFullBufferQueue.Count() )
203 PRINT(_L("CFileWriter::Write() writing async"));
204 PRINT((_L("e_cfilewriter_write_startwrite 1")));
205 iOutputFile->Write( *iFullBufferQueue[0], iStatus );
206 PRINT((_L("e_cfilewriter_write_startwrite 0")));
207 iAsyncWritingOngoing = ETrue;
215 PRINT(_L("CFileWriter::Write() out"));
216 PRINT((_L("e_cfilewriter_write 0")));
220 // -----------------------------------------------------------------------------
221 // CFileWriter::Flush( const TDesC8& aBuf )
222 // Flush internal buffers to disk.
223 // (other items were commented in a header).
224 // -----------------------------------------------------------------------------
226 TInt CFileWriter::Flush( const TDesC8& aBuf )
228 PRINT(_L("CFileWriter::Flush() in"));
229 PRINT((_L("e_cfilewriter_flush 1")));
231 if ( !iMemReadyForWriting )
236 iWritingStarted = ETrue;
238 PRINT((_L("e_cfilewriter_flush_adddatatobuf 1")));
239 TInt error = AddDataToBuffer( aBuf );
240 if ( error != KErrNone )
244 PRINT((_L("e_cfilewriter_flush_adddatatobuf 0")));
246 PRINT((_L("CFileWriter::Flush() FullCount: %d "), iFullBufferQueue.Count()));
249 if ( iAsyncWritingOngoing )
251 PRINT((_L("CFileWriter::Flush() Waiting async write to complete")));
252 PRINT((_L("e_cfilewriter_flush_waitasynctostop 1")));
253 User::WaitForRequest( iStatus );
254 PRINT((_L("e_cfilewriter_flush_waitasynctostop 0")));
255 PRINT((_L("CFileWriter::Flush() Async write done, flushing")));
257 if (error != KErrNone)
259 PRINT((_L("CFileWriter::Flush() call runL leave, error: %d"), error));
264 while ( iFullBufferQueue.Count() )
266 PRINT((_L("e_cfilewriter_flush_writequeue_sync 1")));
267 error = iOutputFile->Write( *iFullBufferQueue[0] );
268 PRINT((_L("e_cfilewriter_flush_writequeue_sync 0")));
269 PRINT((_L("e_cfilewriter_flush_remove_buf 1")));
270 if ( error == KErrNone )
272 UpdateOutputFileSize();
273 iFullBufferQueue[0]->Des().Zero();
274 if ( iEmptyBufferQueue.Append( iFullBufferQueue[0] ) )
276 PRINT(_L("CFileWriter::Flush() Append failed"));
277 delete ( iFullBufferQueue[0] );
279 iFullBufferQueue.Remove( 0 );
283 PRINT((_L("CFileWriter::Flush() fullBufQueue write failed, error: %d"), error));
287 PRINT((_L("e_cfilewriter_flush_remove_buf 0")));
290 if ( iInputBuf->Length() )
292 PRINT((_L("e_cfilewriter_flush_writeinput_sync 1")));
293 error = iOutputFile->Write( *iInputBuf );
294 PRINT((_L("e_cfilewriter_flush_writeinput_sync 0")));
295 if ( error == KErrNone )
297 UpdateOutputFileSize();
298 iInputBuf->Des().Zero();
302 PRINT((_L("CFileWriter::Flush() inputbuf write failed, error: %d"), error));
309 PRINT((_L("CFileWriter::Flush() FullCount: %d <= Should be 0"), iFullBufferQueue.Count()));
310 PRINT(_L("CFileWriter::Flush() out"));
311 PRINT((_L("e_cfilewriter_flush 0")));
316 // -----------------------------------------------------------------------------
317 // CFileWriter::SetOutputBufferSize( TOutputBufferSize aBufferSize )
318 // Set output buffer sizes.
319 // (other items were commented in a header).
320 // -----------------------------------------------------------------------------
322 TInt CFileWriter::SetOutputBufferSize( TOutputBufferSize aBufferSize, MP4Handle aHandle )
324 MP4HandleImp handle = (MP4HandleImp)aHandle;
327 if ( iWritingStarted )
332 if ( aBufferSize == EBufferSizeSmall )
334 size = iOutputBufferSizeSmall;
336 else if ( aBufferSize == EBufferSizeLarge )
338 size = iOutputBufferSizeLarge;
340 else if ( aBufferSize == EBufferSizeCustom )
342 size = handle->mediaWriteBufferSize;
349 if ( size == iOutputBufferSize )
355 iOutputBufferSize = size;
358 iMemReadyForWriting = EFalse;
361 iEmptyBufferQueue.ResetAndDestroy();
362 iFullBufferQueue.ResetAndDestroy();
364 TRAPD(err, AllocateBuffersL() );
368 // -----------------------------------------------------------------------------
369 // CFileWriter::SetOutputBufferCount( MP4Handle aHandle )
370 // Set output buffer count.
371 // (other items were commented in a header).
372 // -----------------------------------------------------------------------------
374 void CFileWriter::SetOutputBufferCount( MP4Handle aHandle )
376 MP4HandleImp handle = (MP4HandleImp)aHandle;
378 if ( handle->writeBufferMaxCount >= 6 )
380 iMaxOutputBufHardLimit = handle->writeBufferMaxCount;
381 iMaxOutputBufSoftLimit = KFileWriterMinBufferCount + ((iMaxOutputBufHardLimit-KFileWriterMinBufferCount)/2);
386 // -----------------------------------------------------------------------------
387 // CFileWriter::AddDataToBuffer( const TDesC8& aBuf )
388 // Writes incoming data to internal buffers and buffer queues..
389 // (other items were commented in a header).
390 // -----------------------------------------------------------------------------
392 TInt CFileWriter::AddDataToBuffer( const TDesC8& aBuf )
394 PRINT(_L("CFileWriter::AddDataToBuffer() in"));
396 TInt byteswritten = 0;
398 TInt available = 0; // Available bytes in write buffer
399 TInt error = KErrNone;
401 if ( iError != KErrNone )
403 PRINT((_L("CFileWriter::AddDataToBuffer() out, RunL iError: %d"), iError));
407 if ( iInputBuf == NULL )
412 while (byteswritten < aBuf.Length() )
414 available = iOutputBufferSize - iInputBuf->Length();
418 numbytes = aBuf.Length() - byteswritten;
419 if (numbytes > available)
421 numbytes = available;
423 iInputBuf->Des().Append( aBuf.Mid( byteswritten, numbytes ) );
424 byteswritten += numbytes;
426 else // Buffer is full, write it to disk
428 // input is full, move full inputbuf to full buf queue
429 if ( iFullBufferQueue.Append( iInputBuf ) != KErrNone )
431 PRINT(_L("CFileWriter::AddDataToBuffer() Append failed"));
435 if ( iEmptyBufferQueue.Count() == 0 )
437 // no empty buffers in queue, allocating new one
438 TRAP(error, iInputBuf = HBufC8::NewL( iOutputBufferSize ));
439 if ( error != KErrNone )
441 PRINT((_L("CFileWriter::AddDataToBuffer(), memory alloc failed: %d"), error));
449 iInputBuf = iEmptyBufferQueue[ 0 ];
450 iEmptyBufferQueue.Remove( 0 );
455 PRINT((_L("CFileWriter::AddDataToBuffer() out, error: %d"), error));
459 // -----------------------------------------------------------------------------
460 // CFileWriter::AllocateBuffersL()
461 // Allocates input and output buffers.
462 // (other items were commented in a header).
463 // -----------------------------------------------------------------------------
465 void CFileWriter::AllocateBuffersL()
467 PRINT((_L("CFileWriter::AllocateBuffersL() in, outbufsize: %d"), iOutputBufferSize));
470 iMemReadyForWriting = EFalse;
472 iInputBuf = HBufC8::NewL( iOutputBufferSize );
473 for( TInt i=0; i<KFileWriterMinBufferCount; i++ )
475 buf = HBufC8::NewL( iOutputBufferSize );
476 err = iEmptyBufferQueue.Append( buf );
483 iMemReadyForWriting = ETrue;
484 PRINT((_L("CFileWriter::AllocateBuffersL() out")));
487 // -----------------------------------------------------------------------------
488 // CFileWriter::DoCancel()
489 // From CActive Cancels async request.
490 // -----------------------------------------------------------------------------
492 void CFileWriter::DoCancel()
496 // -----------------------------------------------------------------------------
497 // CFileWriter::RunL()
498 // From CActive Called when async request completes.
499 // -----------------------------------------------------------------------------
501 void CFileWriter::RunL()
503 PRINT(_L("CFileWriter::RunL() in"));
504 PRINT((_L("e_cfilewriter_runl 1")));
505 iAsyncWritingOngoing = EFalse;
507 if ( iStatus == KErrNone )
509 UpdateOutputFileSize();
510 iFullBufferQueue[0]->Des().Zero();
511 iError = iEmptyBufferQueue.Append( iFullBufferQueue[0] );
514 PRINT((_L("CFileWriter::RunL() Append failed 1 %d"), iError ));
515 delete ( iFullBufferQueue[0] );
516 iFullBufferQueue.Remove( 0 );
519 iFullBufferQueue.Remove( 0 );
523 PRINT((_L("CFileWriter::RunL() Write error in previous async: %d "), iStatus.Int() ));
524 iError = iStatus.Int();
528 PRINT((_L("CFileWriter::RunL() Buffer written, Status: Full:%d Empty:%d Filesize:%Ld"), iFullBufferQueue.Count(), iEmptyBufferQueue.Count(), iOutputFileSize ));
532 PRINT(_L("CFileWriter::RunL() out, flushing"));
533 PRINT((_L("e_cfilewriter_runl 0")));
537 if ( iFullBufferQueue.Count() >= iMaxOutputBufHardLimit )
539 while ( iFullBufferQueue.Count() > iMaxOutputBufSoftLimit )
541 PRINT((_L("e_cfilewriter_runl_write 1")));
542 iError = iOutputFile->Write( *iFullBufferQueue[0]);
543 PRINT((_L("e_cfilewriter_runl_write 0")));
544 if ( iError == KErrNone )
546 UpdateOutputFileSize();
547 iFullBufferQueue[0]->Des().Zero();
548 iError = iEmptyBufferQueue.Append( iFullBufferQueue[0] );
551 PRINT((_L("CFileWriter::RunL() Append failed 2 %d"), iError));
552 delete ( iFullBufferQueue[0] );
553 iFullBufferQueue.Remove( 0 );
556 iFullBufferQueue.Remove( 0 );
557 PRINT((_L("CFileWriter::RunL() Hardlimit : Buffer sync written, Status: Full:%d Empty:%d Filesize:%Ld"), iFullBufferQueue.Count(), iEmptyBufferQueue.Count(), iOutputFileSize ));
561 PRINT((_L("CFileWriter::RunL() Write error: %d "), iError));
567 if ( iFullBufferQueue.Count() >= iMaxOutputBufSoftLimit )
569 PRINT((_L("e_cfilewriter_runl_outfile_write 1")));
570 iError = iOutputFile->Write( *iFullBufferQueue[0]);
571 PRINT((_L("e_cfilewriter_runl_outfile_write 0")));
572 if ( iError == KErrNone )
574 UpdateOutputFileSize();
575 iFullBufferQueue[0]->Des().Zero();
576 iError = iEmptyBufferQueue.Append( iFullBufferQueue[0] );
579 PRINT((_L("CFileWriter::RunL() Append failed 3 %d"), iError));
580 delete ( iFullBufferQueue[0] );
581 iFullBufferQueue.Remove( 0 );
584 iFullBufferQueue.Remove( 0 );
585 PRINT((_L("CFileWriter::RunL() Softlimit : Buffer sync written, Status: Full:%d Empty:%d Filesize:%Ld"), iFullBufferQueue.Count(), iEmptyBufferQueue.Count(), iOutputFileSize ));
589 PRINT((_L("CFileWriter::RunL() Write error: %d "), iError));
594 if ( iFullBufferQueue.Count() )
596 PRINT((_L("e_cfilewriter_runl_outfile2_write 1")));
597 iOutputFile->Write( *iFullBufferQueue[0], iStatus );
598 PRINT((_L("e_cfilewriter_runl_outfile2_write 0")));
599 iAsyncWritingOngoing = ETrue;
606 PRINT((_L("e_cfilewriter_runl 0")));
607 PRINT((_L("CFileWriter::RunL() out, iError=%d"), iError));