|         |      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 the License "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:  Implementation of CHttpCacheStreamHandler | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18 // INCLUDE FILES | 
|         |     19 #include <f32file.h> | 
|         |     20 #include "HttpCacheStreamHandler.h" | 
|         |     21 #include "HttpCacheEntry.h" | 
|         |     22 #include "HttpCacheUtil.h" | 
|         |     23 #include "HttpCacheHandler.h" | 
|         |     24 #include <centralrepository.h> | 
|         |     25 #include <SysUtilDomainCRKeys.h> | 
|         |     26  | 
|         |     27 // EXTERNAL DATA STRUCTURES | 
|         |     28  | 
|         |     29 // EXTERNAL FUNCTION PROTOTYPES | 
|         |     30  | 
|         |     31 // CONSTANTS | 
|         |     32 const TInt KHttpCacheActiveCount = 20; | 
|         |     33 const TInt KBufferSize = 32768; | 
|         |     34 #if 0 | 
|         |     35 const TInt KHttpCacheChunkSize = 2048; | 
|         |     36 #endif // 0 | 
|         |     37 // MACROS | 
|         |     38  | 
|         |     39 // LOCAL CONSTANTS AND MACROS | 
|         |     40  | 
|         |     41 // MODULE DATA STRUCTURES | 
|         |     42  | 
|         |     43 // LOCAL FUNCTION PROTOTYPES | 
|         |     44  | 
|         |     45 // FORWARD DECLARATIONS | 
|         |     46  | 
|         |     47 // ============================= LOCAL FUNCTIONS =============================== | 
|         |     48  | 
|         |     49 // ============================ MEMBER FUNCTIONS =============================== | 
|         |     50  | 
|         |     51 // ----------------------------------------------------------------------------- | 
|         |     52 // CHttpCacheStreamEntry::CHttpCacheStreamEntry | 
|         |     53 // C++ default constructor can NOT contain any code, that | 
|         |     54 // might leave. | 
|         |     55 // ----------------------------------------------------------------------------- | 
|         |     56 // | 
|         |     57 CHttpCacheStreamEntry::CHttpCacheStreamEntry( | 
|         |     58     RFs& aRfs, | 
|         |     59     CHttpCacheEntry& aHttpCacheEntry, | 
|         |     60     TDriveUnit aDrive, | 
|         |     61     TInt64 aCriticalLevel ) | 
|         |     62     : iRfs( aRfs ), iHttpCacheEntry( &aHttpCacheEntry ), iDrive( aDrive ), iCriticalLevel( aCriticalLevel ) | 
|         |     63     { | 
|         |     64     } | 
|         |     65  | 
|         |     66 // ----------------------------------------------------------------------------- | 
|         |     67 // CHttpCacheStreamEntry::ConstructL | 
|         |     68 // Symbian 2nd phase constructor can leave. | 
|         |     69 // ----------------------------------------------------------------------------- | 
|         |     70 // | 
|         |     71 void CHttpCacheStreamEntry::ConstructL() | 
|         |     72     { | 
|         |     73     // consistency check on header/body files | 
|         |     74     // open the file or create one | 
|         |     75     iFileOk = ( iHttpCacheEntry->State() == CHttpCacheEntry::ECacheUninitialized ? CreateNewFilesL() : OpenCacheFiles() ); | 
|         |     76     if( !iFileOk ) | 
|         |     77         { | 
|         |     78         User::Leave( KErrCorrupt ); | 
|         |     79         } | 
|         |     80     else if( iFileOk && iHttpCacheEntry->State() == CHttpCacheEntry::ECacheUninitialized ) | 
|         |     81         { | 
|         |     82         iHttpCacheEntry->SetState( CHttpCacheEntry::ECacheInitialized ); | 
|         |     83         } | 
|         |     84     iCacheBuffer = HBufC8::NewL( KBufferSize ); | 
|         |     85     } | 
|         |     86  | 
|         |     87 // ----------------------------------------------------------------------------- | 
|         |     88 // CHttpCacheStreamEntry::NewL | 
|         |     89 // Two-phased constructor. | 
|         |     90 // ----------------------------------------------------------------------------- | 
|         |     91 // | 
|         |     92 CHttpCacheStreamEntry* CHttpCacheStreamEntry::NewL( | 
|         |     93     RFs& aRfs, | 
|         |     94     CHttpCacheEntry& aHttpCacheEntry, | 
|         |     95     TDriveUnit aDrive, | 
|         |     96     TInt64 aCriticalLevel ) | 
|         |     97     { | 
|         |     98     CHttpCacheStreamEntry* self = new( ELeave ) CHttpCacheStreamEntry( aRfs, | 
|         |     99         aHttpCacheEntry, aDrive, aCriticalLevel ); | 
|         |    100  | 
|         |    101     CleanupStack::PushL( self ); | 
|         |    102     self->ConstructL(); | 
|         |    103     CleanupStack::Pop(); | 
|         |    104  | 
|         |    105     return self; | 
|         |    106     } | 
|         |    107  | 
|         |    108 // Destructor | 
|         |    109 CHttpCacheStreamEntry::~CHttpCacheStreamEntry() | 
|         |    110     { | 
|         |    111     // commit changes | 
|         |    112     if( iFileOk ) | 
|         |    113         { | 
|         |    114         iHeaderFile.Close(); | 
|         |    115         iBodyFile.Close(); | 
|         |    116         } | 
|         |    117     delete iCacheBuffer; | 
|         |    118     } | 
|         |    119  | 
|         |    120 // ----------------------------------------------------------------------------- | 
|         |    121 // CHttpCacheStreamEntry::Erase | 
|         |    122 // | 
|         |    123 // ----------------------------------------------------------------------------- | 
|         |    124 // | 
|         |    125 void CHttpCacheStreamEntry::Erase() | 
|         |    126     { | 
|         |    127     // | 
|         |    128     HttpCacheUtil::WriteUrlToLog( 0, _L( "erase files associated with" ), iHttpCacheEntry->Url() ); | 
|         |    129     iHeaderFile.Close(); | 
|         |    130     iBodyFile.Close(); | 
|         |    131     // dont care about return vales | 
|         |    132     // as we cannot do much | 
|         |    133     TFileName bodyFileName; | 
|         |    134     // get body filename | 
|         |    135     BodyFileName( bodyFileName ); | 
|         |    136  | 
|         |    137     TFileName headerFileName; | 
|         |    138     HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName ); | 
|         |    139     // | 
|         |    140     TInt status; | 
|         |    141     status = iRfs.Delete( bodyFileName ); | 
|         |    142     HttpCacheUtil::WriteLog( 0, bodyFileName, status ); | 
|         |    143     // | 
|         |    144     status = iRfs.Delete( headerFileName ); | 
|         |    145     HttpCacheUtil::WriteLog( 0, headerFileName, status ); | 
|         |    146     // do not close them twice | 
|         |    147     iFileOk = EFalse; | 
|         |    148     } | 
|         |    149  | 
|         |    150 // ----------------------------------------------------------------------------- | 
|         |    151 // CHttpCacheStreamEntry::HeadersL | 
|         |    152 // | 
|         |    153 // ----------------------------------------------------------------------------- | 
|         |    154 // | 
|         |    155 HBufC8* CHttpCacheStreamEntry::HeadersL() | 
|         |    156     { | 
|         |    157     // | 
|         |    158     HBufC8* headerStr = NULL; | 
|         |    159     TInt headerLen( 0 ); | 
|         |    160     TInt err( iHeaderFile.Size( headerLen ) ); | 
|         |    161     // | 
|         |    162     if( err == KErrNone && headerLen > 0 ) | 
|         |    163         { | 
|         |    164         headerStr = HBufC8::NewL( headerLen ); | 
|         |    165         TPtr8 ptr( headerStr->Des() ); | 
|         |    166         // read headers | 
|         |    167         iHeaderFile.Read( 0, ptr, headerLen ); | 
|         |    168         } | 
|         |    169     return headerStr; | 
|         |    170     } | 
|         |    171  | 
|         |    172 // ----------------------------------------------------------------------------- | 
|         |    173 // CHttpCacheStreamEntry::NextChunkL | 
|         |    174 // | 
|         |    175 // ----------------------------------------------------------------------------- | 
|         |    176 // | 
|         |    177 HBufC8* CHttpCacheStreamEntry::NextChunkL( | 
|         |    178     TBool& aLastChunk ) | 
|         |    179     { | 
|         |    180     HBufC8* bodyStr = NULL; | 
|         |    181 #if 0 | 
|         |    182     // incremental chunk handling | 
|         |    183     TInt size; | 
|         |    184     TInt contentSize( iBodyFile.Size( size ) ); | 
|         |    185     size = Min( KHttpCacheChunkSize, contentSize ); | 
|         |    186  | 
|         |    187     bodyStr = HBufC8::NewL( size ); | 
|         |    188     TPtr8 ptr( bodyStr->Des() ); | 
|         |    189     // | 
|         |    190     iBodyFile.Read( ptr, size ); | 
|         |    191     // check if we are at the end of the file | 
|         |    192     aLastChunk = ( bodyStr->Length() != size ); | 
|         |    193 #else // 0 | 
|         |    194     // read body | 
|         |    195     TInt size; | 
|         |    196     TInt err( iBodyFile.Size( size ) ); | 
|         |    197     if( err == KErrNone && size > 0 ) | 
|         |    198         { | 
|         |    199         bodyStr = HBufC8::NewL( size ); | 
|         |    200         TPtr8 ptr( bodyStr->Des() ); | 
|         |    201         // | 
|         |    202         iBodyFile.Read( ptr, size ); | 
|         |    203         } | 
|         |    204     aLastChunk = ETrue; | 
|         |    205 #endif // 0 | 
|         |    206     return bodyStr; | 
|         |    207     } | 
|         |    208  | 
|         |    209 // ----------------------------------------------------------------------------- | 
|         |    210 // CHttpCacheStreamEntry::SaveHeaders | 
|         |    211 // | 
|         |    212 // ----------------------------------------------------------------------------- | 
|         |    213 // | 
|         |    214 TInt CHttpCacheStreamEntry::SaveHeaders( | 
|         |    215     const TDesC8& aHeaderStr ) | 
|         |    216     { | 
|         |    217     TInt save( KErrNone ); | 
|         |    218  | 
|         |    219     if( aHeaderStr.Length() ) | 
|         |    220         { | 
|         |    221         // below critical level | 
|         |    222         TBool below( ETrue ); | 
|         |    223  | 
|         |    224         below = DiskSpaceBelowCriticalLevel( aHeaderStr.Length() ); | 
|         |    225  | 
|         |    226         if( !below ) | 
|         |    227             { | 
|         |    228             // save headers | 
|         |    229             // Don't force a flush, as the File Server takes care of write and read consistency. | 
|         |    230             iHttpCacheEntry->SetHeaderSize( aHeaderStr.Length() ); | 
|         |    231             save = iHeaderFile.Write( aHeaderStr ); | 
|         |    232             } | 
|         |    233         else | 
|         |    234             { | 
|         |    235             save = KErrDiskFull; | 
|         |    236             } | 
|         |    237         } | 
|         |    238     return save; | 
|         |    239     } | 
|         |    240  | 
|         |    241 // ----------------------------------------------------------------------------- | 
|         |    242 // CHttpCacheStreamEntry::RemoveHeaders | 
|         |    243 // | 
|         |    244 // ----------------------------------------------------------------------------- | 
|         |    245 // | 
|         |    246 void CHttpCacheStreamEntry::RemoveHeaders() | 
|         |    247     { | 
|         |    248     // destroy data | 
|         |    249     iHeaderFile.SetSize( 0 ); | 
|         |    250     iHttpCacheEntry->SetHeaderSize( 0 ); | 
|         |    251     } | 
|         |    252  | 
|         |    253 // ----------------------------------------------------------------------------- | 
|         |    254 // CHttpCacheStreamEntry::SaveBodyData | 
|         |    255 // | 
|         |    256 // ----------------------------------------------------------------------------- | 
|         |    257 // | 
|         |    258 TInt CHttpCacheStreamEntry::SaveBodyData( | 
|         |    259     const TDesC8& aBodyStr ) | 
|         |    260     { | 
|         |    261     TBool save( KErrNone ); | 
|         |    262     TInt bodyLength( aBodyStr.Length() ); | 
|         |    263  | 
|         |    264     if( bodyLength ) | 
|         |    265         { | 
|         |    266         TPtr8 buffer( iCacheBuffer->Des() ); | 
|         |    267         if( buffer.Length() + bodyLength > buffer.MaxLength() ) | 
|         |    268             { | 
|         |    269             // | 
|         |    270             HBufC8* overflowBuffer = NULL; | 
|         |    271             TInt cut( -1 ); | 
|         |    272             // running out of space | 
|         |    273             TPtrC8 writePtr; | 
|         |    274             if( buffer.Length() == 0 ) | 
|         |    275                 { | 
|         |    276                 // buffer is empty and the body is bigger than the buffer | 
|         |    277                 writePtr.Set( aBodyStr ); | 
|         |    278                 } | 
|         |    279             else | 
|         |    280                 { | 
|         |    281                 cut =  buffer.MaxLength() - buffer.Length(); | 
|         |    282                 // enough space for the leftover? | 
|         |    283                 if( bodyLength - cut > buffer.MaxLength() ) | 
|         |    284                     { | 
|         |    285                     // not enough | 
|         |    286                     // put the buffer and the body together and | 
|         |    287                     // write it in one go. | 
|         |    288                     overflowBuffer = HBufC8::New( buffer.Length() + bodyLength ); | 
|         |    289                     if( !overflowBuffer ) | 
|         |    290                         { | 
|         |    291                         return KErrNoMemory; | 
|         |    292                         } | 
|         |    293                     TPtr8 overflowPtr( overflowBuffer->Des() ); | 
|         |    294                     overflowPtr.Copy( buffer ); | 
|         |    295                     overflowPtr.Append( aBodyStr ); | 
|         |    296                     writePtr.Set( overflowBuffer->Des() ); | 
|         |    297                     // empty buffer | 
|         |    298                     buffer.Zero(); | 
|         |    299                     // no leftover left | 
|         |    300                     cut = -1; | 
|         |    301                     } | 
|         |    302                 else | 
|         |    303                     { | 
|         |    304                     // fill the 32k | 
|         |    305                     buffer.Append( aBodyStr.Left( cut ) ); | 
|         |    306                     writePtr.Set( buffer ); | 
|         |    307                     } | 
|         |    308                 } | 
|         |    309  | 
|         |    310             // write to the disk | 
|         |    311             TBool below; | 
|         |    312             below = DiskSpaceBelowCriticalLevel( writePtr.Length() ); | 
|         |    313  | 
|         |    314             if( !below ) | 
|         |    315                 { | 
|         |    316                 // write body | 
|         |    317                 save = iBodyFile.Write( writePtr ); | 
|         |    318                 } | 
|         |    319             else | 
|         |    320                 { | 
|         |    321                 save = KErrDiskFull; | 
|         |    322                 // reset buffers | 
|         |    323                 buffer.Zero(); | 
|         |    324                 } | 
|         |    325             // | 
|         |    326             if( save == KErrNone && cut >= 0 ) | 
|         |    327                 { | 
|         |    328                 // copy the leftover in to the buffer | 
|         |    329                 buffer.Copy( aBodyStr.Mid( cut ) ); | 
|         |    330                 } | 
|         |    331             delete overflowBuffer; | 
|         |    332             } | 
|         |    333         else | 
|         |    334             { | 
|         |    335             buffer.Append( aBodyStr ); | 
|         |    336             save = KErrNone; | 
|         |    337             } | 
|         |    338         // update size information | 
|         |    339         iHttpCacheEntry->SetSize( iHttpCacheEntry->Size() + bodyLength ); | 
|         |    340         } | 
|         |    341     return save; | 
|         |    342     } | 
|         |    343  | 
|         |    344 // ----------------------------------------------------------------------------- | 
|         |    345 // CHttpCacheStreamEntry::RemoveBodyData | 
|         |    346 // | 
|         |    347 // ----------------------------------------------------------------------------- | 
|         |    348 // | 
|         |    349 void CHttpCacheStreamEntry::RemoveBodyData() | 
|         |    350     { | 
|         |    351     // destroy data | 
|         |    352     iCacheBuffer->Des().Zero(); | 
|         |    353     iBodyFile.SetSize( 0 ); | 
|         |    354     iHttpCacheEntry->SetSize( 0 ); | 
|         |    355     } | 
|         |    356  | 
|         |    357 // ----------------------------------------------------------------------------- | 
|         |    358 // CHttpCacheStreamEntry::Flush | 
|         |    359 // | 
|         |    360 // ----------------------------------------------------------------------------- | 
|         |    361 // | 
|         |    362 TInt CHttpCacheStreamEntry::Flush() | 
|         |    363     { | 
|         |    364     TInt saveOk( KErrNone ); | 
|         |    365  | 
|         |    366     if( iCacheBuffer->Length() ) | 
|         |    367         { | 
|         |    368         TPtr8 bufferPtr( iCacheBuffer->Des() ); | 
|         |    369  | 
|         |    370         TBool below; | 
|         |    371         below = DiskSpaceBelowCriticalLevel( bufferPtr.Length() ); | 
|         |    372  | 
|         |    373         if( !below ) | 
|         |    374             { | 
|         |    375             // append body | 
|         |    376             saveOk = iBodyFile.Write( bufferPtr ); | 
|         |    377             } | 
|         |    378         else | 
|         |    379             { | 
|         |    380             saveOk = KErrDiskFull; | 
|         |    381             } | 
|         |    382         bufferPtr.Zero(); | 
|         |    383         } | 
|         |    384     return saveOk; | 
|         |    385     } | 
|         |    386  | 
|         |    387 // ----------------------------------------------------------------------------- | 
|         |    388 // CHttpCacheStreamEntry::OpenCacheFiles | 
|         |    389 // | 
|         |    390 // ----------------------------------------------------------------------------- | 
|         |    391 // | 
|         |    392 TBool CHttpCacheStreamEntry::OpenCacheFiles() | 
|         |    393     { | 
|         |    394     TInt statusHeader; | 
|         |    395     TInt statusBody; | 
|         |    396     // | 
|         |    397     TFileName bodyFileName; | 
|         |    398     // get body filename | 
|         |    399     BodyFileName( bodyFileName ); | 
|         |    400     // header filename | 
|         |    401     TFileName headerFileName; | 
|         |    402     // | 
|         |    403     HttpCacheUtil::GetHeaderFileName( bodyFileName, headerFileName ); | 
|         |    404  | 
|         |    405     statusHeader = iHeaderFile.Open( iRfs, headerFileName, EFileShareExclusive | EFileWrite ); | 
|         |    406     statusBody = iBodyFile.Open( iRfs, bodyFileName, EFileShareExclusive | EFileWrite ); | 
|         |    407     return ( statusHeader == KErrNone && statusBody == KErrNone ); | 
|         |    408     } | 
|         |    409  | 
|         |    410 // ----------------------------------------------------------------------------- | 
|         |    411 // CHttpCacheStreamEntry::CreateNewFilesL | 
|         |    412 // | 
|         |    413 // ----------------------------------------------------------------------------- | 
|         |    414 // | 
|         |    415 TBool CHttpCacheStreamEntry::CreateNewFilesL() | 
|         |    416     { | 
|         |    417     TInt statusHeader( KErrNotFound ); | 
|         |    418     TInt statusBody( KErrNotFound ); | 
|         |    419     TPath sessionPath; | 
|         |    420     User::LeaveIfError( iRfs.SessionPath( sessionPath ) ); | 
|         |    421  | 
|         |    422     //Given the full URL, generates a fully qualified path for saving the HTTP response | 
|         |    423     HBufC* bodyFileName = HttpCacheUtil::GenerateNameLC( iHttpCacheEntry->Url(), sessionPath ); | 
|         |    424     TPtrC bodyFileNamePtr( *bodyFileName ); | 
|         |    425     // get header file name | 
|         |    426     TFileName headerFileName; | 
|         |    427     HttpCacheUtil::GetHeaderFileName( bodyFileNamePtr, headerFileName ); | 
|         |    428  | 
|         |    429     // create a file or replace if it exists.  | 
|         |    430     statusBody = iBodyFile.Replace( iRfs, bodyFileNamePtr, EFileShareExclusive | EFileWrite ); | 
|         |    431     if( statusBody == KErrNone ) | 
|         |    432         { | 
|         |    433         // header file should not fail | 
|         |    434         statusHeader = iHeaderFile.Replace( iRfs, headerFileName, EFileShareExclusive | EFileWrite ); | 
|         |    435         } | 
|         |    436     // | 
|         |    437     TBool fileOk( statusHeader == KErrNone && statusBody == KErrNone ); | 
|         |    438 #ifdef __CACHELOG__  | 
|         |    439     HttpCacheUtil::WriteUrlToLog( 0, bodyFileNamePtr, iHttpCacheEntry->Url() ); | 
|         |    440 #endif  | 
|         |    441  | 
|         |    442     // | 
|         |    443     if( fileOk ) | 
|         |    444         { | 
|         |    445         iHttpCacheEntry->SetFileNameL( bodyFileNamePtr ); | 
|         |    446 #ifdef __CACHELOG__  | 
|         |    447         HttpCacheUtil::WriteUrlToLog( 0, _L8("files are fine") ); | 
|         |    448 #endif  | 
|         |    449         } | 
|         |    450     else | 
|         |    451         { | 
|         |    452         // corrupt entry. delete the file | 
|         |    453         if( statusBody == KErrNone ) | 
|         |    454             { | 
|         |    455             iRfs.Delete( bodyFileNamePtr ); | 
|         |    456             } | 
|         |    457         // ??? | 
|         |    458         __ASSERT_DEBUG( EFalse, | 
|         |    459             User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    460         } | 
|         |    461     CleanupStack::PopAndDestroy( bodyFileName ); | 
|         |    462     return fileOk; | 
|         |    463     } | 
|         |    464  | 
|         |    465 // ----------------------------------------------------------------------------- | 
|         |    466 // CHttpCacheStreamEntry::BodyFileName | 
|         |    467 // | 
|         |    468 // ----------------------------------------------------------------------------- | 
|         |    469 // | 
|         |    470 void CHttpCacheStreamEntry::BodyFileName( | 
|         |    471     TFileName& aBodyFileName ) | 
|         |    472     { | 
|         |    473     TFileName bodyFileName; | 
|         |    474     aBodyFileName.Copy( iHttpCacheEntry->Filename()  ); | 
|         |    475     } | 
|         |    476  | 
|         |    477 // ----------------------------------------------------------------------------- | 
|         |    478 // CHttpCacheStreamEntry::BodyFileName | 
|         |    479 // | 
|         |    480 // ----------------------------------------------------------------------------- | 
|         |    481 // | 
|         |    482 TBool CHttpCacheStreamEntry::DiskSpaceBelowCriticalLevel( | 
|         |    483     TInt aContentSize ) | 
|         |    484     { | 
|         |    485     TVolumeInfo vinfo; | 
|         |    486     TInt errorCode = iRfs.Volume( vinfo, iDrive ); | 
|         |    487  | 
|         |    488     return( errorCode != KErrNone || ( vinfo.iFree - aContentSize ) <= iCriticalLevel ); | 
|         |    489     } | 
|         |    490  | 
|         |    491 // ----------------------------------------------------------------------------- | 
|         |    492 // CHttpCacheStreamHandler::CHttpCacheStreamHandler | 
|         |    493 // C++ default constructor can NOT contain any code, that | 
|         |    494 // might leave. | 
|         |    495 // ----------------------------------------------------------------------------- | 
|         |    496 // | 
|         |    497 CHttpCacheStreamHandler::CHttpCacheStreamHandler() : iDiskFull( EFalse ) | 
|         |    498     { | 
|         |    499     // change the iDiskFull back to false if somebody freed some disk space. | 
|         |    500     } | 
|         |    501  | 
|         |    502 // ----------------------------------------------------------------------------- | 
|         |    503 // CHttpCacheStreamHandler::ConstructL | 
|         |    504 // Symbian 2nd phase constructor can leave. | 
|         |    505 // ----------------------------------------------------------------------------- | 
|         |    506 // | 
|         |    507 void CHttpCacheStreamHandler::ConstructL( | 
|         |    508     const TDesC& aDirectory, | 
|         |    509     TInt aCriticalLevel ) | 
|         |    510     { | 
|         |    511     User::LeaveIfError( iRfs.Connect() ); | 
|         |    512     // set path for the entries | 
|         |    513     iRfs.SetSessionPath( aDirectory ); | 
|         |    514     iActiveEntries = new( ELeave )CArrayPtrFlat<CHttpCacheStreamEntry>( KHttpCacheActiveCount ); | 
|         |    515     // get drive letter for sysutil | 
|         |    516     TParsePtrC pathParser( aDirectory ); | 
|         |    517     iDrive = pathParser.Drive(); | 
|         |    518     iCriticalLevel = aCriticalLevel; | 
|         |    519     } | 
|         |    520  | 
|         |    521 // ----------------------------------------------------------------------------- | 
|         |    522 // CHttpCacheStreamHandler::NewL | 
|         |    523 // Two-phased constructor. | 
|         |    524 // ----------------------------------------------------------------------------- | 
|         |    525 // | 
|         |    526 CHttpCacheStreamHandler* CHttpCacheStreamHandler::NewL( | 
|         |    527     const TDesC& aDirectory , | 
|         |    528     TInt aCriticalLevel) | 
|         |    529     { | 
|         |    530     CHttpCacheStreamHandler* self = new( ELeave ) CHttpCacheStreamHandler(); | 
|         |    531  | 
|         |    532     CleanupStack::PushL( self ); | 
|         |    533     self->ConstructL( aDirectory , aCriticalLevel); | 
|         |    534     CleanupStack::Pop(); | 
|         |    535  | 
|         |    536     return self; | 
|         |    537     } | 
|         |    538  | 
|         |    539 // Destructor | 
|         |    540 CHttpCacheStreamHandler::~CHttpCacheStreamHandler() | 
|         |    541     { | 
|         |    542     if( iActiveEntries ) | 
|         |    543         { | 
|         |    544         iActiveEntries->ResetAndDestroy(); | 
|         |    545         } | 
|         |    546     delete iActiveEntries; | 
|         |    547     iRfs.Close(); | 
|         |    548     } | 
|         |    549  | 
|         |    550 // ----------------------------------------------------------------------------- | 
|         |    551 // CHttpCacheStreamHandler::AttachL | 
|         |    552 // | 
|         |    553 // ----------------------------------------------------------------------------- | 
|         |    554 // | 
|         |    555 TBool CHttpCacheStreamHandler::AttachL( | 
|         |    556     CHttpCacheEntry& aCacheEntry ) | 
|         |    557     { | 
|         |    558 #ifdef __CACHELOG__ | 
|         |    559     // check for duplicates | 
|         |    560     for( TInt i = 0; i < iActiveEntries->Count(); i++ ) | 
|         |    561         { | 
|         |    562         __ASSERT_DEBUG( iActiveEntries->At( i )->CacheEntry() != &aCacheEntry, | 
|         |    563             User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    564         } | 
|         |    565 #endif // __CACHELOG__ | 
|         |    566     TBool attached( ETrue ); | 
|         |    567     // create and save stream entry | 
|         |    568     CHttpCacheStreamEntry* streamEntry = NULL; | 
|         |    569  | 
|         |    570     TRAPD( err, streamEntry = CHttpCacheStreamEntry::NewL( iRfs, aCacheEntry, iDrive, iCriticalLevel ) ); | 
|         |    571     if( err == KErrCorrupt ) | 
|         |    572         { | 
|         |    573         // | 
|         |    574         attached = EFalse; | 
|         |    575         } | 
|         |    576     else if( err == KErrNoMemory ) | 
|         |    577         { | 
|         |    578         User::Leave( err ); | 
|         |    579         } | 
|         |    580     else if( streamEntry ) | 
|         |    581         { | 
|         |    582         iActiveEntries->AppendL( streamEntry ); | 
|         |    583         } | 
|         |    584     return attached; | 
|         |    585     } | 
|         |    586  | 
|         |    587 // ----------------------------------------------------------------------------- | 
|         |    588 // CHttpCacheStreamHandler::Detach | 
|         |    589 // | 
|         |    590 // ----------------------------------------------------------------------------- | 
|         |    591 // | 
|         |    592 void CHttpCacheStreamHandler::Detach( | 
|         |    593     const CHttpCacheEntry& aCacheEntry ) | 
|         |    594     { | 
|         |    595     TInt index; | 
|         |    596     CHttpCacheStreamEntry* streamEntry = FindStreamEntry( aCacheEntry, &index ); | 
|         |    597     __ASSERT_DEBUG( streamEntry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    598  | 
|         |    599     if( streamEntry ) | 
|         |    600         { | 
|         |    601         delete streamEntry; | 
|         |    602         iActiveEntries->Delete( index ); | 
|         |    603         } | 
|         |    604     } | 
|         |    605  | 
|         |    606 // ----------------------------------------------------------------------------- | 
|         |    607 // CHttpCacheStreamHandler::Erase | 
|         |    608 // | 
|         |    609 // ----------------------------------------------------------------------------- | 
|         |    610 // | 
|         |    611 void CHttpCacheStreamHandler::Erase( | 
|         |    612     const CHttpCacheEntry& aCacheEntry ) | 
|         |    613     { | 
|         |    614     TInt index; | 
|         |    615     CHttpCacheStreamEntry* streamEntry = FindStreamEntry( aCacheEntry, &index ); | 
|         |    616     __ASSERT_DEBUG( streamEntry != NULL, User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    617  | 
|         |    618     if( streamEntry ) | 
|         |    619         { | 
|         |    620         streamEntry->Erase(); | 
|         |    621         // | 
|         |    622         iContentSize-=aCacheEntry.Size(); | 
|         |    623         iContentSize-=aCacheEntry.HeaderSize(); | 
|         |    624         } | 
|         |    625     } | 
|         |    626  | 
|         |    627 // ----------------------------------------------------------------------------- | 
|         |    628 // CHttpCacheStreamHandler::HeadersL | 
|         |    629 // | 
|         |    630 // ----------------------------------------------------------------------------- | 
|         |    631 // | 
|         |    632 HBufC8* CHttpCacheStreamHandler::HeadersL( | 
|         |    633     CHttpCacheEntry& aCacheEntry ) | 
|         |    634     { | 
|         |    635     CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    636     HBufC8* headerStr = NULL; | 
|         |    637     // | 
|         |    638     __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    639     // | 
|         |    640     if( entry ) | 
|         |    641         { | 
|         |    642         headerStr = entry->HeadersL(); | 
|         |    643         } | 
|         |    644     return headerStr; | 
|         |    645     } | 
|         |    646  | 
|         |    647 // ----------------------------------------------------------------------------- | 
|         |    648 // CHttpCacheStreamHandler::NextChunkL | 
|         |    649 // | 
|         |    650 // ----------------------------------------------------------------------------- | 
|         |    651 // | 
|         |    652 HBufC8* CHttpCacheStreamHandler::NextChunkL( | 
|         |    653     CHttpCacheEntry& aCacheEntry, | 
|         |    654     TBool& aLastChunk ) | 
|         |    655     { | 
|         |    656     // | 
|         |    657     CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    658     HBufC8* bodyStr = NULL; | 
|         |    659     // | 
|         |    660     __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    661     // | 
|         |    662     if( entry ) | 
|         |    663         { | 
|         |    664         bodyStr = entry->NextChunkL( aLastChunk ); | 
|         |    665         } | 
|         |    666     return bodyStr; | 
|         |    667     } | 
|         |    668  | 
|         |    669 // ----------------------------------------------------------------------------- | 
|         |    670 // CHttpCacheStreamHandler::SaveHeaders | 
|         |    671 // | 
|         |    672 // ----------------------------------------------------------------------------- | 
|         |    673 // | 
|         |    674 TBool CHttpCacheStreamHandler::SaveHeaders( | 
|         |    675     CHttpCacheEntry& aCacheEntry, | 
|         |    676     const TDesC8& aHeaderStr ) | 
|         |    677     { | 
|         |    678     TBool saved( KErrGeneral ); | 
|         |    679     if( !iDiskFull ) | 
|         |    680         { | 
|         |    681         CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    682         // | 
|         |    683         __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    684         // | 
|         |    685         if( entry ) | 
|         |    686             { | 
|         |    687             saved = entry->SaveHeaders( aHeaderStr ); | 
|         |    688             // update content size in cache | 
|         |    689             if( saved == KErrNone ) | 
|         |    690                 { | 
|         |    691                 iContentSize+=aHeaderStr.Length(); | 
|         |    692                 } | 
|         |    693             else if( saved == KErrDiskFull ) | 
|         |    694                 { | 
|         |    695                 iDiskFull = ETrue; | 
|         |    696                 } | 
|         |    697             } | 
|         |    698         } | 
|         |    699     return( saved == KErrNone ); | 
|         |    700     } | 
|         |    701  | 
|         |    702 // ----------------------------------------------------------------------------- | 
|         |    703 // CHttpCacheStreamHandler::RemoveHeaders | 
|         |    704 // | 
|         |    705 // ----------------------------------------------------------------------------- | 
|         |    706 // | 
|         |    707 void CHttpCacheStreamHandler::RemoveHeaders( | 
|         |    708     CHttpCacheEntry& aCacheEntry ) | 
|         |    709     { | 
|         |    710     CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    711     // | 
|         |    712     __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    713     // | 
|         |    714     if( entry ) | 
|         |    715         { | 
|         |    716         iContentSize-=aCacheEntry.HeaderSize(); | 
|         |    717         entry->RemoveHeaders(); | 
|         |    718         } | 
|         |    719     } | 
|         |    720  | 
|         |    721 // ----------------------------------------------------------------------------- | 
|         |    722 // CHttpCacheStreamHandler::SaveBodyData | 
|         |    723 // | 
|         |    724 // ----------------------------------------------------------------------------- | 
|         |    725 // | 
|         |    726 TBool CHttpCacheStreamHandler::SaveBodyData( | 
|         |    727     CHttpCacheEntry& aCacheEntry, | 
|         |    728     const TDesC8& aBodyStr ) | 
|         |    729     { | 
|         |    730     TInt saved( KErrGeneral ); | 
|         |    731     if( !iDiskFull ) | 
|         |    732         { | 
|         |    733         CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    734         // | 
|         |    735         __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    736         // | 
|         |    737         if( entry ) | 
|         |    738             { | 
|         |    739             saved = entry->SaveBodyData( aBodyStr ); | 
|         |    740             if( saved == KErrNone ) | 
|         |    741                 { | 
|         |    742                 iContentSize+=aBodyStr.Length(); | 
|         |    743                 } | 
|         |    744             else if( saved == KErrDiskFull ) | 
|         |    745                 { | 
|         |    746                 iDiskFull = ETrue; | 
|         |    747                 } | 
|         |    748             } | 
|         |    749         } | 
|         |    750     return( saved == KErrNone ); | 
|         |    751     } | 
|         |    752  | 
|         |    753 // ----------------------------------------------------------------------------- | 
|         |    754 // CHttpCacheStreamHandler::RemoveBodyData | 
|         |    755 // | 
|         |    756 // ----------------------------------------------------------------------------- | 
|         |    757 // | 
|         |    758 void CHttpCacheStreamHandler::RemoveBodyData( | 
|         |    759     CHttpCacheEntry& aCacheEntry ) | 
|         |    760     { | 
|         |    761     CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    762     // | 
|         |    763     __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    764     // | 
|         |    765     if( entry ) | 
|         |    766         { | 
|         |    767         iContentSize-=aCacheEntry.Size(); | 
|         |    768         entry->RemoveBodyData(); | 
|         |    769         } | 
|         |    770     } | 
|         |    771  | 
|         |    772 // ----------------------------------------------------------------------------- | 
|         |    773 // CHttpCacheStreamHandler::Flush | 
|         |    774 // | 
|         |    775 // ----------------------------------------------------------------------------- | 
|         |    776 // | 
|         |    777 TBool CHttpCacheStreamHandler::Flush( | 
|         |    778     CHttpCacheEntry& aCacheEntry ) | 
|         |    779     { | 
|         |    780     TInt saved( KErrGeneral ); | 
|         |    781     if( !iDiskFull ) | 
|         |    782         { | 
|         |    783         CHttpCacheStreamEntry* entry = FindStreamEntry( aCacheEntry ); | 
|         |    784         // | 
|         |    785         __ASSERT_DEBUG( entry != NULL,  User::Panic( _L("cacheHandler Panic"), KErrCorrupt )  ); | 
|         |    786         // | 
|         |    787         if( entry ) | 
|         |    788             { | 
|         |    789             saved = entry->Flush(); | 
|         |    790             // | 
|         |    791             if( saved == KErrDiskFull ) | 
|         |    792                 { | 
|         |    793                 iDiskFull = ETrue; | 
|         |    794                 } | 
|         |    795             } | 
|         |    796         } | 
|         |    797     return( saved == KErrNone ); | 
|         |    798     } | 
|         |    799  | 
|         |    800 // ----------------------------------------------------------------------------- | 
|         |    801 // CHttpCacheStreamHandler::FindStreamEntry | 
|         |    802 // | 
|         |    803 // ----------------------------------------------------------------------------- | 
|         |    804 // | 
|         |    805 CHttpCacheStreamEntry* CHttpCacheStreamHandler::FindStreamEntry( | 
|         |    806     const CHttpCacheEntry& aCacheEntry, | 
|         |    807     TInt* aIndex ) | 
|         |    808     { | 
|         |    809     CHttpCacheStreamEntry* streamEntry = NULL; | 
|         |    810  | 
|         |    811     for( TInt i = 0; i < iActiveEntries->Count(); i++ ) | 
|         |    812         { | 
|         |    813         CHttpCacheStreamEntry* entry = iActiveEntries->At( i ); | 
|         |    814  | 
|         |    815         if( entry && entry->CacheEntry() == &aCacheEntry ) | 
|         |    816             { | 
|         |    817             streamEntry = entry; | 
|         |    818             if( aIndex ) | 
|         |    819                 { | 
|         |    820                 *aIndex = i; | 
|         |    821                 } | 
|         |    822             break; | 
|         |    823             } | 
|         |    824         } | 
|         |    825     return streamEntry; | 
|         |    826     } | 
|         |    827  | 
|         |    828 //  End of File |