--- a/webengine/osswebengine/cache/src/HttpCacheStreamHandler.cpp Mon Mar 30 12:54:55 2009 +0300
+++ b/webengine/osswebengine/cache/src/HttpCacheStreamHandler.cpp Fri May 08 08:25:06 2009 +0300
@@ -30,7 +30,6 @@
// CONSTANTS
const TInt KHttpCacheActiveCount = 20;
-const TInt KBufferSize = 32768;
#if 0
const TInt KHttpCacheChunkSize = 2048;
#endif // 0
@@ -49,454 +48,13 @@
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::CHttpCacheStreamEntry
-// C++ default constructor can NOT contain any code, that
-// might leave.
-// -----------------------------------------------------------------------------
-//
-CHttpCacheStreamEntry::CHttpCacheStreamEntry(
- RFs& aRfs,
- CHttpCacheEntry& aHttpCacheEntry,
- TDriveUnit aDrive,
- TInt64 aCriticalLevel )
- : iRfs( aRfs ), iHttpCacheEntry( &aHttpCacheEntry ), iDrive( aDrive ), iCriticalLevel( aCriticalLevel )
- {
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::ConstructL
-// Symbian 2nd phase constructor can leave.
-// -----------------------------------------------------------------------------
-//
-void CHttpCacheStreamEntry::ConstructL()
- {
- // consistency check on header/body files
- // open the file or create one
- iFileOk = ( iHttpCacheEntry->State() == CHttpCacheEntry::ECacheUninitialized ? CreateNewFilesL() : OpenCacheFiles() );
- if( !iFileOk )
- {
- User::Leave( KErrCorrupt );
- }
- else if( iFileOk && iHttpCacheEntry->State() == CHttpCacheEntry::ECacheUninitialized )
- {
- iHttpCacheEntry->SetState( CHttpCacheEntry::ECacheInitialized );
- }
- iCacheBuffer = HBufC8::NewL( KBufferSize );
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::NewL
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-//
-CHttpCacheStreamEntry* CHttpCacheStreamEntry::NewL(
- RFs& aRfs,
- CHttpCacheEntry& aHttpCacheEntry,
- TDriveUnit aDrive,
- TInt64 aCriticalLevel )
- {
- CHttpCacheStreamEntry* self = new( ELeave ) CHttpCacheStreamEntry( aRfs,
- aHttpCacheEntry, aDrive, aCriticalLevel );
-
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop();
-
- return self;
- }
-
-// Destructor
-CHttpCacheStreamEntry::~CHttpCacheStreamEntry()
- {
- // commit changes
- if( iFileOk )
- {
- iHeaderFile.Close();
- iBodyFile.Close();
- }
- delete iCacheBuffer;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::Erase
-//
-// -----------------------------------------------------------------------------
-//
-void CHttpCacheStreamEntry::Erase()
- {
- //
- HttpCacheUtil::WriteUrlToLog( 0, _L( "erase files associated with" ), iHttpCacheEntry->Url() );
- iHeaderFile.Close();
- iBodyFile.Close();
- // dont care about return vales
- // as we cannot do much
- TFileName bodyFileName;
- // get body filename
- BodyFileName( bodyFileName );
-
- TFileName headerFileName;
- HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName );
- //
- TInt status;
- status = iRfs.Delete( bodyFileName );
- HttpCacheUtil::WriteLog( 0, bodyFileName, status );
- //
- status = iRfs.Delete( headerFileName );
- HttpCacheUtil::WriteLog( 0, headerFileName, status );
- // do not close them twice
- iFileOk = EFalse;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::HeadersL
-//
-// -----------------------------------------------------------------------------
-//
-HBufC8* CHttpCacheStreamEntry::HeadersL()
- {
- //
- HBufC8* headerStr = NULL;
- TInt headerLen( 0 );
- TInt err( iHeaderFile.Size( headerLen ) );
- //
- if( err == KErrNone && headerLen > 0 )
- {
- headerStr = HBufC8::NewL( headerLen );
- TPtr8 ptr( headerStr->Des() );
- // read headers
- iHeaderFile.Read( 0, ptr, headerLen );
- }
- return headerStr;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::NextChunkL
-//
-// -----------------------------------------------------------------------------
-//
-HBufC8* CHttpCacheStreamEntry::NextChunkL(
- TBool& aLastChunk )
- {
- HBufC8* bodyStr = NULL;
-#if 0
- // incremental chunk handling
- TInt size;
- TInt contentSize( iBodyFile.Size( size ) );
- size = Min( KHttpCacheChunkSize, contentSize );
-
- bodyStr = HBufC8::NewL( size );
- TPtr8 ptr( bodyStr->Des() );
- //
- iBodyFile.Read( ptr, size );
- // check if we are at the end of the file
- aLastChunk = ( bodyStr->Length() != size );
-#else // 0
- // read body
- TInt size;
- TInt err( iBodyFile.Size( size ) );
- if( err == KErrNone && size > 0 )
- {
- bodyStr = HBufC8::NewL( size );
- TPtr8 ptr( bodyStr->Des() );
- //
- iBodyFile.Read( ptr, size );
- }
- aLastChunk = ETrue;
-#endif // 0
- return bodyStr;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::SaveHeaders
-//
-// -----------------------------------------------------------------------------
-//
-TInt CHttpCacheStreamEntry::SaveHeaders(
- const TDesC8& aHeaderStr )
- {
- TInt save( KErrNone );
-
- if( aHeaderStr.Length() )
- {
- // below critical level
- TBool below( ETrue );
-
- below = DiskSpaceBelowCriticalLevel( aHeaderStr.Length() );
-
- if( !below )
- {
- // save headers
- // Don't force a flush, as the File Server takes care of write and read consistency.
- iHttpCacheEntry->SetHeaderSize( aHeaderStr.Length() );
- save = iHeaderFile.Write( aHeaderStr );
- }
- else
- {
- save = KErrDiskFull;
- }
- }
- return save;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::RemoveHeaders
-//
-// -----------------------------------------------------------------------------
-//
-void CHttpCacheStreamEntry::RemoveHeaders()
- {
- // destroy data
- iHeaderFile.SetSize( 0 );
- iHttpCacheEntry->SetHeaderSize( 0 );
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::SaveBodyData
-//
-// -----------------------------------------------------------------------------
-//
-TInt CHttpCacheStreamEntry::SaveBodyData(
- const TDesC8& aBodyStr )
- {
- TBool save( KErrNone );
- TInt bodyLength( aBodyStr.Length() );
-
- if( bodyLength )
- {
- TPtr8 buffer( iCacheBuffer->Des() );
- if( buffer.Length() + bodyLength > buffer.MaxLength() )
- {
- //
- HBufC8* overflowBuffer = NULL;
- TInt cut( -1 );
- // running out of space
- TPtrC8 writePtr;
- if( buffer.Length() == 0 )
- {
- // buffer is empty and the body is bigger than the buffer
- writePtr.Set( aBodyStr );
- }
- else
- {
- cut = buffer.MaxLength() - buffer.Length();
- // enough space for the leftover?
- if( bodyLength - cut > buffer.MaxLength() )
- {
- // not enough
- // put the buffer and the body together and
- // write it in one go.
- overflowBuffer = HBufC8::New( buffer.Length() + bodyLength );
- if( !overflowBuffer )
- {
- return KErrNoMemory;
- }
- TPtr8 overflowPtr( overflowBuffer->Des() );
- overflowPtr.Copy( buffer );
- overflowPtr.Append( aBodyStr );
- writePtr.Set( overflowBuffer->Des() );
- // empty buffer
- buffer.Zero();
- // no leftover left
- cut = -1;
- }
- else
- {
- // fill the 32k
- buffer.Append( aBodyStr.Left( cut ) );
- writePtr.Set( buffer );
- }
- }
-
- // write to the disk
- TBool below;
- below = DiskSpaceBelowCriticalLevel( writePtr.Length() );
-
- if( !below )
- {
- // write body
- save = iBodyFile.Write( writePtr );
- }
- else
- {
- save = KErrDiskFull;
- // reset buffers
- buffer.Zero();
- }
- //
- if( save == KErrNone && cut >= 0 )
- {
- // copy the leftover in to the buffer
- buffer.Copy( aBodyStr.Mid( cut ) );
- }
- delete overflowBuffer;
- }
- else
- {
- buffer.Append( aBodyStr );
- save = KErrNone;
- }
- // update size information
- iHttpCacheEntry->SetSize( iHttpCacheEntry->Size() + bodyLength );
- }
- return save;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::RemoveBodyData
-//
-// -----------------------------------------------------------------------------
-//
-void CHttpCacheStreamEntry::RemoveBodyData()
- {
- // destroy data
- iCacheBuffer->Des().Zero();
- iBodyFile.SetSize( 0 );
- iHttpCacheEntry->SetSize( 0 );
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::Flush
-//
-// -----------------------------------------------------------------------------
-//
-TInt CHttpCacheStreamEntry::Flush()
- {
- TInt saveOk( KErrNone );
-
- if( iCacheBuffer->Length() )
- {
- TPtr8 bufferPtr( iCacheBuffer->Des() );
-
- TBool below;
- below = DiskSpaceBelowCriticalLevel( bufferPtr.Length() );
-
- if( !below )
- {
- // append body
- saveOk = iBodyFile.Write( bufferPtr );
- }
- else
- {
- saveOk = KErrDiskFull;
- }
- bufferPtr.Zero();
- }
- return saveOk;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::OpenCacheFiles
-//
-// -----------------------------------------------------------------------------
-//
-TBool CHttpCacheStreamEntry::OpenCacheFiles()
- {
- TInt statusHeader;
- TInt statusBody;
- //
- TFileName bodyFileName;
- // get body filename
- BodyFileName( bodyFileName );
- // header filename
- TFileName headerFileName;
- //
- HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName );
-
- statusHeader = iHeaderFile.Open( iRfs, headerFileName, EFileShareExclusive | EFileWrite );
- statusBody = iBodyFile.Open( iRfs, bodyFileName, EFileShareExclusive | EFileWrite );
- return ( statusHeader == KErrNone && statusBody == KErrNone );
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::CreateNewFilesL
-//
-// -----------------------------------------------------------------------------
-//
-TBool CHttpCacheStreamEntry::CreateNewFilesL()
- {
- TInt statusHeader( KErrNotFound );
- TInt statusBody( KErrNotFound );
- TPath sessionPath;
- User::LeaveIfError( iRfs.SessionPath( sessionPath ) );
-
- //Given the full URL, generates a fully qualified path for saving the HTTP response
- HBufC* bodyFileName = HttpCacheUtil::GenerateNameLC( iHttpCacheEntry->Url(), sessionPath );
- TPtrC bodyFileNamePtr( *bodyFileName );
- // get header file name
- TFileName headerFileName;
- HttpCacheUtil::GetHeaderFileName( bodyFileNamePtr, headerFileName );
-
- // create a file or replace if it exists.
- statusBody = iBodyFile.Replace( iRfs, bodyFileNamePtr, EFileShareExclusive | EFileWrite );
- if( statusBody == KErrNone )
- {
- // header file should not fail
- statusHeader = iHeaderFile.Replace( iRfs, headerFileName, EFileShareExclusive | EFileWrite );
- }
- //
- TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone );
-#ifdef __CACHELOG__
- HttpCacheUtil::WriteUrlToLog( 0, bodyFileNamePtr, iHttpCacheEntry->Url() );
-#endif
-
- //
- if( fileOk )
- {
- iHttpCacheEntry->SetFileNameL( bodyFileNamePtr );
-#ifdef __CACHELOG__
- HttpCacheUtil::WriteUrlToLog( 0, _L8("files are fine") );
-#endif
- }
- else
- {
- // corrupt entry. delete the file
- if( statusBody == KErrNone )
- {
- iRfs.Delete( bodyFileNamePtr );
- }
- // ???
- __ASSERT_DEBUG( EFalse,
- User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- }
- CleanupStack::PopAndDestroy( bodyFileName );
- return fileOk;
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::BodyFileName
-//
-// -----------------------------------------------------------------------------
-//
-void CHttpCacheStreamEntry::BodyFileName(
- TFileName& aBodyFileName )
- {
- TFileName bodyFileName;
- aBodyFileName.Copy( iHttpCacheEntry->Filename() );
- }
-
-// -----------------------------------------------------------------------------
-// CHttpCacheStreamEntry::BodyFileName
-//
-// -----------------------------------------------------------------------------
-//
-TBool CHttpCacheStreamEntry::DiskSpaceBelowCriticalLevel(
- TInt aContentSize )
- {
- TVolumeInfo vinfo;
- TInt errorCode = iRfs.Volume( vinfo, iDrive );
-
- return( errorCode != KErrNone || ( vinfo.iFree - aContentSize ) <= iCriticalLevel );
- }
-
-// -----------------------------------------------------------------------------
// CHttpCacheStreamHandler::CHttpCacheStreamHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
-CHttpCacheStreamHandler::CHttpCacheStreamHandler() : iDiskFull( EFalse )
+CHttpCacheStreamHandler::CHttpCacheStreamHandler()
{
- // change the iDiskFull back to false if somebody freed some disk space.
}
// -----------------------------------------------------------------------------
@@ -511,7 +69,7 @@
User::LeaveIfError( iRfs.Connect() );
// set path for the entries
iRfs.SetSessionPath( aDirectory );
- iActiveEntries = new( ELeave )CArrayPtrFlat<CHttpCacheStreamEntry>( KHttpCacheActiveCount );
+ iActiveEntries = new( ELeave )CArrayPtrFlat<CHttpCacheEntry>( KHttpCacheActiveCount );
// get drive letter for sysutil
TParsePtrC pathParser( aDirectory );
iDrive = pathParser.Drive();
@@ -536,14 +94,18 @@
return self;
}
+// -----------------------------------------------------------------------------
// Destructor
+// -----------------------------------------------------------------------------
+//
CHttpCacheStreamHandler::~CHttpCacheStreamHandler()
{
- if( iActiveEntries )
+ if ( iActiveEntries )
{
iActiveEntries->ResetAndDestroy();
}
delete iActiveEntries;
+
iRfs.Close();
}
@@ -552,36 +114,50 @@
//
// -----------------------------------------------------------------------------
//
-TBool CHttpCacheStreamHandler::AttachL(
- CHttpCacheEntry& aCacheEntry )
+TBool CHttpCacheStreamHandler::AttachL( CHttpCacheEntry& aCacheEntry )
{
#ifdef __CACHELOG__
// check for duplicates
- for( TInt i = 0; i < iActiveEntries->Count(); i++ )
+ for ( TInt i = 0; i < iActiveEntries->Count(); i++ )
{
- __ASSERT_DEBUG( iActiveEntries->At( i )->CacheEntry() != &aCacheEntry,
- User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ __ASSERT_DEBUG( iActiveEntries->At( i ) != &aCacheEntry,
+ User::Panic( _L("cacheStreamHandler Panic"), KErrCorrupt ) );
}
#endif // __CACHELOG__
- TBool attached( ETrue );
- // create and save stream entry
- CHttpCacheStreamEntry* streamEntry = NULL;
+
+ TBool cacheFilesOpened( EFalse );
- TRAPD( err, streamEntry = CHttpCacheStreamEntry::NewL( iRfs, aCacheEntry, iDrive, iCriticalLevel ) );
- if( err == KErrCorrupt )
+ if ( aCacheEntry.CacheFilesOpened() )
{
- //
- attached = EFalse;
+ // Cache files already opened, no need to reopen
+ cacheFilesOpened = ETrue;
+ }
+ else if ( aCacheEntry.State() == CHttpCacheEntry::ECacheUninitialized )
+ {
+ // Create new cache files, they don't already exist
+ cacheFilesOpened = CreateNewFilesL( aCacheEntry );
}
- else if( err == KErrNoMemory )
+ else
{
- User::Leave( err );
+ // Open existing cache files
+ cacheFilesOpened = OpenCacheFiles( aCacheEntry );
}
- else if( streamEntry )
+
+ if ( cacheFilesOpened )
{
- iActiveEntries->AppendL( streamEntry );
+ // Add to our active array, if not already there
+ TInt index( -1 );
+ FindCacheEntryIndex( aCacheEntry, &index );
+ if ( index == -1 )
+ {
+ iActiveEntries->AppendL( &aCacheEntry );
+ }
}
- return attached;
+
+ aCacheEntry.SetCacheFilesOpened( cacheFilesOpened );
+
+ // Return ETrue, if files opened and attached
+ return cacheFilesOpened;
}
// -----------------------------------------------------------------------------
@@ -589,39 +165,90 @@
//
// -----------------------------------------------------------------------------
//
-void CHttpCacheStreamHandler::Detach(
- const CHttpCacheEntry& aCacheEntry )
+void CHttpCacheStreamHandler::Detach( CHttpCacheEntry& aCacheEntry )
{
- TInt index;
- CHttpCacheStreamEntry* streamEntry = FindStreamEntry( aCacheEntry, &index );
- __ASSERT_DEBUG( streamEntry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ // Close the files, this will commit changes
+ if ( aCacheEntry.CacheFilesOpened() )
+ {
+ aCacheEntry.BodyFile().Close();
+ aCacheEntry.HeaderFile().Close();
+ aCacheEntry.SetCacheFilesOpened( EFalse );
+ }
- if( streamEntry )
+ // Delete from our active array
+ TInt index( -1 );
+ FindCacheEntryIndex( (const CHttpCacheEntry&)aCacheEntry, &index );
+ if ( index >= 0 )
{
- delete streamEntry;
iActiveEntries->Delete( index );
}
}
// -----------------------------------------------------------------------------
-// CHttpCacheStreamHandler::Erase
+// CHttpCacheStreamHandler::EraseCacheFile
//
// -----------------------------------------------------------------------------
//
-void CHttpCacheStreamHandler::Erase(
- const CHttpCacheEntry& aCacheEntry )
+void CHttpCacheStreamHandler::EraseCacheFile( CHttpCacheEntry& aCacheEntry )
{
- TInt index;
- CHttpCacheStreamEntry* streamEntry = FindStreamEntry( aCacheEntry, &index );
- __ASSERT_DEBUG( streamEntry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
+ HttpCacheUtil::WriteUrlToLog( 0, _L( "CHttpCacheStreamHandler::Erase - erase files associated with" ), aCacheEntry.Url() );
+
+ aCacheEntry.HeaderFile().Close();
+ aCacheEntry.BodyFile().Close();
+ aCacheEntry.SetCacheFilesOpened( EFalse );
+
+ // Get body filename
+ TFileName bodyFileName = aCacheEntry.Filename();
+
+ // Get header filename
+ TFileName headerFileName;
+ HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName );
+
+ TInt statusBody( KErrNotFound );
+ statusBody = iRfs.Delete( bodyFileName );
+
+ TInt statusHeader( KErrNotFound );
+ statusHeader = iRfs.Delete( headerFileName );
+
+ // Adjust the size
+ iContentSize -= aCacheEntry.BodySize();
+ iContentSize -= aCacheEntry.HeaderSize();
- if( streamEntry )
- {
- streamEntry->Erase();
- //
- iContentSize-=aCacheEntry.Size();
- iContentSize-=aCacheEntry.HeaderSize();
+#ifdef __CACHELOG__
+ if ( statusBody != KErrNone ) {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::Erase - ERROR bodyFile delete"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ statusBody,
+ ELogFileErrorCode );
+ }
+ else {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::Erase - SUCCESS bodyFile delete"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ aCacheEntry.BodySize(),
+ ELogEntrySize );
}
+ if ( statusHeader != KErrNone ) {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::Erase - ERROR headerFile delete"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ statusHeader,
+ ELogFileErrorCode );
+ }
+ else {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::Erase - SUCCESS headerFile delete"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ aCacheEntry.BodySize(),
+ ELogEntrySize );
+ }
+#endif //__CACHELOG__
+
}
// -----------------------------------------------------------------------------
@@ -629,18 +256,26 @@
//
// -----------------------------------------------------------------------------
//
-HBufC8* CHttpCacheStreamHandler::HeadersL(
- CHttpCacheEntry& aCacheEntry )
+HBufC8* CHttpCacheStreamHandler::HeadersL( CHttpCacheEntry& aCacheEntry )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
HBufC8* headerStr = NULL;
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
+ TInt headerLen( 0 );
+ TInt err( KErrNone );
+
+ if ( !aCacheEntry.CacheFilesOpened() )
{
- headerStr = entry->HeadersL();
+ OpenCacheFiles( aCacheEntry );
}
+
+ err = aCacheEntry.HeaderFile().Size( headerLen );
+ if ( err == KErrNone && headerLen > 0 )
+ {
+ headerStr = HBufC8::NewL( headerLen );
+ TPtr8 ptr( headerStr->Des() );
+ // read headers
+ aCacheEntry.HeaderFile().Read( 0, ptr, headerLen );
+ }
+
return headerStr;
}
@@ -653,16 +288,47 @@
CHttpCacheEntry& aCacheEntry,
TBool& aLastChunk )
{
- //
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
HBufC8* bodyStr = NULL;
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
+ // Read whole body
+ TInt size( 0 );
+ TInt sizeErr( KErrNone );
+
+ if ( !aCacheEntry.CacheFilesOpened() )
+ {
+ OpenCacheFiles( aCacheEntry );
+ }
+
+ sizeErr = aCacheEntry.BodyFile().Size( size );
+ if ( sizeErr == KErrNone && size > 0 )
{
- bodyStr = entry->NextChunkL( aLastChunk );
+ bodyStr = HBufC8::NewL( size );
+ TPtr8 ptr( bodyStr->Des() );
+
+ TInt readErr( KErrNone );
+ readErr = aCacheEntry.BodyFile().Read( ptr, size );
+
+#ifdef __CACHELOG__
+ if ( readErr != KErrNone ) {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ readErr,
+ ELogFileErrorCode );
+ }
+ else {
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CCHttpCacheStreamEntry::NextChunkL - bodyFile.read"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ ptr.Length(),
+ ELogEntrySize );
+ }
+#endif // __CACHELOG__
+
}
+ aLastChunk = ETrue;
+
return bodyStr;
}
@@ -675,28 +341,28 @@
CHttpCacheEntry& aCacheEntry,
const TDesC8& aHeaderStr )
{
- TBool saved( KErrGeneral );
- if( !iDiskFull )
+ TBool headerSaved( EFalse );
+
+ if ( !aCacheEntry.CacheFilesOpened() )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
+ OpenCacheFiles( aCacheEntry );
+ }
+
+ if ( aHeaderStr.Length() && IsDiskSpaceAvailable( aHeaderStr.Length() ) )
+ {
+ // We have space on disk, save headers. Don't force a flush, as the
+ // File Server takes care of write and read consistency.
+ TInt writeErr = aCacheEntry.HeaderFile().Write( aHeaderStr );
+
+ if ( writeErr == KErrNone )
{
- saved = entry->SaveHeaders( aHeaderStr );
- // update content size in cache
- if( saved == KErrNone )
- {
- iContentSize+=aHeaderStr.Length();
- }
- else if( saved == KErrDiskFull )
- {
- iDiskFull = ETrue;
- }
+ aCacheEntry.SetHeaderSize( aHeaderStr.Length() );
+ iContentSize += aHeaderStr.Length();
+ headerSaved = ETrue;
}
}
- return( saved == KErrNone );
+
+ return headerSaved;
}
// -----------------------------------------------------------------------------
@@ -704,18 +370,13 @@
//
// -----------------------------------------------------------------------------
//
-void CHttpCacheStreamHandler::RemoveHeaders(
- CHttpCacheEntry& aCacheEntry )
+void CHttpCacheStreamHandler::RemoveHeaders( CHttpCacheEntry& aCacheEntry )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
- {
- iContentSize-=aCacheEntry.HeaderSize();
- entry->RemoveHeaders();
- }
+ iContentSize -= aCacheEntry.HeaderSize();
+
+ // Destroy data
+ aCacheEntry.HeaderFile().SetSize( 0 );
+ aCacheEntry.SetHeaderSize( 0 );
}
// -----------------------------------------------------------------------------
@@ -727,27 +388,101 @@
CHttpCacheEntry& aCacheEntry,
const TDesC8& aBodyStr )
{
- TInt saved( KErrGeneral );
- if( !iDiskFull )
+ TInt bodySaved( EFalse );
+ TInt newBodyLength( aBodyStr.Length() );
+ TPtr8 buffer( aCacheEntry.CacheBuffer() );
+
+ if ( newBodyLength && buffer.MaxLength() )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
+ // Calculate if we have enough space in the buffer for incoming body
+ if ( buffer.Length() + newBodyLength > buffer.MaxLength() )
{
- saved = entry->SaveBodyData( aBodyStr );
- if( saved == KErrNone )
+ // Incoming data is too big for the buffer
+ HBufC8* overflowBuffer = NULL;
+ TInt bufferSpaceLeft( -1 );
+ TPtrC8 writePtr;
+
+ if ( buffer.Length() == 0 )
+ {
+ // Buffer is empty and the body is bigger than the buffer,
+ // just take all of the incoming data
+ writePtr.Set( aBodyStr );
+ }
+ else
{
- iContentSize+=aBodyStr.Length();
+ // We have some data in buffer, how much space do we have left
+ bufferSpaceLeft = buffer.MaxLength() - buffer.Length();
+
+ if ( newBodyLength - bufferSpaceLeft > buffer.MaxLength() )
+ {
+ // Not enough space, so lets put the buffer and the new
+ // body together and write it in one go.
+ overflowBuffer = HBufC8::New( buffer.Length() + newBodyLength );
+ if ( !overflowBuffer )
+ {
+ return EFalse;
+ }
+
+ TPtr8 overflowPtr( overflowBuffer->Des() );
+ overflowPtr.Copy( buffer );
+ overflowPtr.Append( aBodyStr );
+ writePtr.Set( overflowBuffer->Des() );
+
+ // empty buffer
+ buffer.Zero();
+ // no leftover left
+ bufferSpaceLeft = -1;
+ }
+ else
+ {
+ // Copy what we have enough space for
+ buffer.Append( aBodyStr.Left( bufferSpaceLeft ) );
+ writePtr.Set( buffer );
+ }
}
- else if( saved == KErrDiskFull )
+
+ // Write to the disk, if we have disk space
+ TInt writeErr( KErrNone );
+ if ( IsDiskSpaceAvailable( writePtr.Length() ) )
{
- iDiskFull = ETrue;
+
+ if ( !aCacheEntry.CacheFilesOpened() )
+ {
+ OpenCacheFiles( aCacheEntry );
+ }
+
+ // We have enough disk space, save body
+ TInt writeErr = aCacheEntry.BodyFile().Write( writePtr );
+ bodySaved = ETrue;
+ }
+ else
+ {
+ // We don't have enough disk space, clean up
+ bodySaved = EFalse;
+ buffer.Zero();
}
+
+ if ( writeErr == KErrNone && bufferSpaceLeft >= 0 )
+ {
+ // Copy what we can of the leftover in to the buffer
+ buffer.Copy( aBodyStr.Mid( bufferSpaceLeft ) );
+ }
+ delete overflowBuffer;
}
+ else
+ {
+ // We have enough space in buffer, add and wait for next body
+ // before writing to file
+ buffer.Append( aBodyStr );
+ bodySaved = ETrue;
+ }
+
+ // Body saved, update state
+ aCacheEntry.SetBodySize( aCacheEntry.BodySize() + newBodyLength );
+ iContentSize += aBodyStr.Length();
}
- return( saved == KErrNone );
+
+ return bodySaved;
}
// -----------------------------------------------------------------------------
@@ -755,18 +490,22 @@
//
// -----------------------------------------------------------------------------
//
-void CHttpCacheStreamHandler::RemoveBodyData(
- CHttpCacheEntry& aCacheEntry )
+void CHttpCacheStreamHandler::RemoveBodyData( CHttpCacheEntry& aCacheEntry )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
- {
- iContentSize-=aCacheEntry.Size();
- entry->RemoveBodyData();
- }
+#ifdef __CACHELOG__
+ HttpCacheUtil::WriteLogFilenameAndUrl( 0,
+ _L("CHttpCacheStreamHandler::RemoveBodyData - CLEAR iCacheBuffer, entrySize, and iBodyFile"),
+ aCacheEntry.Filename(),
+ aCacheEntry.Url(),
+ aCacheEntry.BodySize(),
+ ELogEntrySize );
+#endif
+
+ // Remove data
+ iContentSize -= aCacheEntry.BodySize();
+ aCacheEntry.SetBodySize( 0 );
+ aCacheEntry.CacheBuffer().Zero();
+ aCacheEntry.BodyFile().SetSize( 0 );
}
// -----------------------------------------------------------------------------
@@ -774,55 +513,168 @@
//
// -----------------------------------------------------------------------------
//
-TBool CHttpCacheStreamHandler::Flush(
- CHttpCacheEntry& aCacheEntry )
+TBool CHttpCacheStreamHandler::Flush( CHttpCacheEntry& aCacheEntry )
{
- TInt saved( KErrGeneral );
- if( !iDiskFull )
+ TBool saved( EFalse );
+ TInt writeErr( KErrGeneral );
+ TInt cacheBufferLen( aCacheEntry.CacheBuffer().Length() );
+
+ if ( cacheBufferLen && IsDiskSpaceAvailable( cacheBufferLen ) )
{
- CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry );
- //
- __ASSERT_DEBUG( entry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt ) );
- //
- if( entry )
+ // We have enough space, save cache buffer
+ TPtr8 bufferPtr( aCacheEntry.CacheBuffer() );
+ if ( bufferPtr.Length() )
{
- saved = entry->Flush();
- //
- if( saved == KErrDiskFull )
+ if ( !aCacheEntry.CacheFilesOpened() )
{
- iDiskFull = ETrue;
+ OpenCacheFiles( aCacheEntry );
+ }
+
+ writeErr = aCacheEntry.BodyFile().Write( bufferPtr );
+ if ( writeErr == KErrNone )
+ {
+ saved = ETrue;
}
}
+
+ // Clear the buffer
+ bufferPtr.Zero();
}
- return( saved == KErrNone );
+
+ return saved;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheStreamHandler::OpenCacheFiles
+//
+// -----------------------------------------------------------------------------
+//
+TBool CHttpCacheStreamHandler::OpenCacheFiles( CHttpCacheEntry& aCacheEntry )
+ {
+ TInt statusHeader( KErrNotFound );
+ TInt statusBody( KErrNotFound );
+
+ // get body filename
+ TFileName bodyFileName = aCacheEntry.Filename();
+
+ // header filename
+ TFileName headerFileName;
+ HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName );
+
+ statusHeader = aCacheEntry.HeaderFile().Open( iRfs, headerFileName, EFileShareExclusive | EFileWrite );
+ statusBody = aCacheEntry.BodyFile().Open( iRfs, bodyFileName, EFileShareExclusive | EFileWrite );
+
+ TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone );
+ if ( fileOk )
+ {
+ aCacheEntry.SetCacheFilesOpened( ETrue );
+ }
+
+ return fileOk;
}
// -----------------------------------------------------------------------------
-// CHttpCacheStreamHandler::FindStreamEntry
+// CHttpCacheStreamHandler::CreateNewFilesL
//
// -----------------------------------------------------------------------------
//
-CHttpCacheStreamEntry* CHttpCacheStreamHandler::FindStreamEntry(
+TBool CHttpCacheStreamHandler::CreateNewFilesL( CHttpCacheEntry& aCacheEntry )
+ {
+ TInt statusHeader( KErrNotFound );
+ TInt statusBody( KErrNotFound );
+ TPath sessionPath;
+ User::LeaveIfError( iRfs.SessionPath( sessionPath ) );
+
+ // Given the full URL, generates a fully qualified path for saving the HTTP response
+ HBufC* bodyFileName = HttpCacheUtil::GenerateNameLC( aCacheEntry.Url(), sessionPath );
+ TPtrC bodyFileNamePtr( *bodyFileName );
+
+ // Create header file name from body file name
+ TFileName headerFileName;
+ HttpCacheUtil::GetHeaderFileName( bodyFileNamePtr, headerFileName );
+
+ // Create the body file or replace it, if it exists.
+ statusBody = aCacheEntry.BodyFile().Replace( iRfs, bodyFileNamePtr, EFileShareExclusive | EFileWrite );
+ if ( statusBody == KErrNone )
+ {
+ // Header file should not fail
+ statusHeader = aCacheEntry.HeaderFile().Replace( iRfs, headerFileName, EFileShareExclusive | EFileWrite );
+ }
+
+#ifdef __CACHELOG__
+ HttpCacheUtil::WriteUrlToLog( 0, bodyFileNamePtr, aCacheEntry.Url() );
+#endif
+
+ TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone );
+ if ( fileOk )
+ {
+ // Both body and header files created correctly
+ aCacheEntry.SetFileNameL( bodyFileNamePtr );
+ aCacheEntry.SetState( CHttpCacheEntry::ECacheInitialized );
+ }
+ else
+ {
+ // Only the body file created, no header file, delete body file
+ iRfs.Delete( bodyFileNamePtr );
+ iRfs.Delete( headerFileName );
+
+ aCacheEntry.SetBodySize( 0 );
+ aCacheEntry.SetHeaderSize( 0 );
+
+#ifdef __CACHELOG__
+ HttpCacheUtil::WriteLog( 0, _L( "CHttpCacheEntry::CreateNewFilesL - DELETE body file, header file failed" ) );
+#endif
+// __ASSERT_DEBUG( EFalse, User::Panic( _L("CHttpCacheHandler::CreateNewFilesL Panic"), KErrCorrupt ) );
+ }
+
+ CleanupStack::PopAndDestroy( bodyFileName );
+
+ return fileOk;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheStreamHandler::FindCacheEntryIndex
+//
+// -----------------------------------------------------------------------------
+//
+void CHttpCacheStreamHandler::FindCacheEntryIndex(
const CHttpCacheEntry& aCacheEntry,
TInt* aIndex )
{
- CHttpCacheStreamEntry* streamEntry = NULL;
-
- for( TInt i = 0; i < iActiveEntries->Count(); i++ )
+ *aIndex = -1;
+ for ( TInt i = 0; i < iActiveEntries->Count(); i++ )
{
- CHttpCacheStreamEntry* entry = iActiveEntries->At( i );
+ CHttpCacheEntry* entry = iActiveEntries->At( i );
- if( entry && entry->CacheEntry() == &aCacheEntry )
+ if ( entry == &aCacheEntry )
{
- streamEntry = entry;
- if( aIndex )
+ if ( aIndex )
{
*aIndex = i;
}
break;
}
}
- return streamEntry;
+ }
+
+// -----------------------------------------------------------------------------
+// CHttpCacheStreamHandler::IsDiskSpaceAvailable
+//
+// -----------------------------------------------------------------------------
+//
+TBool CHttpCacheStreamHandler::IsDiskSpaceAvailable( TInt aContentSize )
+ {
+ TBool diskSpaceAvailable( EFalse );
+ TVolumeInfo vinfo;
+ TInt errorCode = iRfs.Volume( vinfo, iDrive );
+
+ if ( errorCode == KErrNone && ( vinfo.iFree - aContentSize ) > iCriticalLevel )
+ {
+ // We have space on the disk for the content
+ diskSpaceAvailable = ETrue;
+ }
+
+ return diskSpaceAvailable;
}
// End of File