webengine/osswebengine/cache/src/HttpCachePostponeWriteUtilities.cpp
changeset 10 a359256acfc6
child 11 c8a366e56285
equal deleted inserted replaced
5:10e98eab6f85 10:a359256acfc6
       
     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 CHttpCachePostponeWriteUtilities
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include "HttpCachePostponeWriteUtilities.h"
       
    20 #include "HttpCacheUtil.h"
       
    21 
       
    22 // EXTERNAL DATA STRUCTURES
       
    23 
       
    24 // EXTERNAL FUNCTION PROTOTYPES
       
    25 
       
    26 // CONSTANTS
       
    27 
       
    28 // MACROS
       
    29 
       
    30 // LOCAL CONSTANTS AND MACROS
       
    31 
       
    32 // MODULE DATA STRUCTURES
       
    33 
       
    34 // LOCAL FUNCTION PROTOTYPES
       
    35 
       
    36 // FORWARD DECLARATIONS
       
    37 
       
    38 // ============================= LOCAL FUNCTIONS ===============================
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CHttpCacheEntryAsyncWriteHelper::CHttpCacheEntryAsyncWriteHelper
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 CHttpCacheEntryAsyncWriteHelper::CHttpCacheEntryAsyncWriteHelper(TRequestStatus& aStatus, MHttpCacheWriteSource* aSource, TInt aPriority)
       
    47     : CActive(aPriority),
       
    48       iSignalStatus(aStatus),
       
    49       iSource(aSource)
       
    50     {
       
    51     }
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CHttpCacheEntryAsyncWriteHelper::NewL
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 CHttpCacheEntryAsyncWriteHelper* CHttpCacheEntryAsyncWriteHelper::NewL(MHttpCacheWriteSource* aSource, TRequestStatus& aStatus)
       
    58     {
       
    59     CHttpCacheEntryAsyncWriteHelper *obj = new (ELeave) CHttpCacheEntryAsyncWriteHelper(aStatus, aSource, EPriorityHigh);
       
    60     CleanupStack::PushL(obj);
       
    61     obj->ConstructL();
       
    62     CleanupStack::Pop(obj);
       
    63     return obj;
       
    64     }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CHttpCacheEntryAsyncWriteHelper::~CHttpCacheEntryAsyncWriteHelper
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 CHttpCacheEntryAsyncWriteHelper::~CHttpCacheEntryAsyncWriteHelper()
       
    71     {
       
    72     Cancel();
       
    73     }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CHttpCacheEntryAsyncWriteHelper::DoCancel
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 void CHttpCacheEntryAsyncWriteHelper::DoCancel()
       
    80     {
       
    81     TRequestStatus *stat = &(TRequestStatus&)iSignalStatus;
       
    82     User::RequestComplete(stat, KErrCancel);    // Signal cancellation to the observer.
       
    83     // cannot meaningfully do anything with the unwritten data assuming there is some.
       
    84     // we will clean it up when we are deleted.
       
    85     iSource->BodyFile().Close();
       
    86     iSource->BodyWriteComplete();
       
    87 #ifdef __CACHELOG__
       
    88     HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::DoCancel called on object %08x"), this);
       
    89 #endif
       
    90     }
       
    91 
       
    92 // -----------------------------------------------------------------------------
       
    93 // CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 void CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock()
       
    97     {
       
    98 #ifdef __CACHELOG__
       
    99     HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::WriteNextBodyBlock called on object %08x for block %d"), this, iBodyPart );
       
   100 #endif
       
   101 
       
   102     TPtrC8 bufferPtr( iSource->BodyData().GetSegmentData(iBodyPart) );
       
   103     iSource->BodyFile().Write(bufferPtr, iStatus);
       
   104     }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CHttpCacheEntryAsyncWriteHelper::RunL
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 void CHttpCacheEntryAsyncWriteHelper::RunL()
       
   111     {
       
   112     /* General algorithm.
       
   113      * Write out next section of body data unless done.  Then write out header data.
       
   114      */
       
   115 #ifdef __CACHELOG__
       
   116     HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE: CHttpCacheEntryAsyncWriteHelper::RunL called on object %08x"), this);
       
   117 #endif
       
   118     if ( iSource->BodyData().Count() > iBodyPart )
       
   119         {
       
   120         WriteNextBodyBlock();
       
   121         SetActive();
       
   122         }
       
   123     else
       
   124         {
       
   125 #ifdef __CACHELOG__
       
   126         HttpCacheUtil::WriteFormatLog(0, _L("CACHEPOSTPONE:   - body write completed with status code %d"), iStatus.Int());
       
   127 #endif
       
   128         // Body file writing is complete
       
   129         iSource->BodyFile().Close();
       
   130         iSource->BodyWriteComplete();
       
   131         TRequestStatus *stat = &(TRequestStatus&)iSignalStatus;
       
   132         User::RequestComplete(stat, iStatus.Int()); // signal completion to observer
       
   133         }
       
   134     }
       
   135 
       
   136 // -----------------------------------------------------------------------------
       
   137 // CHttpCacheEntryAsyncWriteHelper::GetResult
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 TInt CHttpCacheEntryAsyncWriteHelper::GetResult()
       
   141     {
       
   142     return iStatus.Int();
       
   143     }
       
   144 
       
   145 // -----------------------------------------------------------------------------
       
   146 // CHttpCacheEntryAsyncWriteHelper::ConstructL
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 void CHttpCacheEntryAsyncWriteHelper::ConstructL()
       
   150     {
       
   151     CActiveScheduler::Add(this);
       
   152     iSource->BodyWriteInProgress();
       
   153     // setup to arrive in RunL when next possible.
       
   154     SetActive();
       
   155     TRequestStatus *stat = &(TRequestStatus&)iStatus;
       
   156     User::RequestComplete(stat, KErrNone);
       
   157     }
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CSegmentedHeapBuffer::~CSegmentedHeapBuffer
       
   161 // -----------------------------------------------------------------------------
       
   162 //
       
   163 CSegmentedHeapBuffer::~CSegmentedHeapBuffer()
       
   164     {
       
   165     Reset();
       
   166     }
       
   167 
       
   168 // -----------------------------------------------------------------------------
       
   169 // CSegmentedHeapBuffer::ConstructL
       
   170 // -----------------------------------------------------------------------------
       
   171 //
       
   172 void CSegmentedHeapBuffer::ConstructL()
       
   173     {
       
   174     }
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 // CSegmentedHeapBuffer::NewL
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 CSegmentedHeapBuffer *CSegmentedHeapBuffer::NewL(TInt aBufferSize, TInt aCompressGranularity)
       
   181     {
       
   182     CSegmentedHeapBuffer *obj= new (ELeave) CSegmentedHeapBuffer(aBufferSize, aCompressGranularity);
       
   183     CleanupStack::PushL(obj);
       
   184     obj->ConstructL();
       
   185     CleanupStack::Pop(obj);
       
   186 
       
   187     return obj;
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CSegmentedHeapBuffer::AppendL
       
   192 // -----------------------------------------------------------------------------
       
   193 //
       
   194 void CSegmentedHeapBuffer::AppendL(TInt& aRemainder, const TDesC8& aDes)
       
   195     {
       
   196     aRemainder = aDes.Length(); // consumed nothing yet.
       
   197     TInt workingLen;
       
   198     TInt workingOffset=0;   // read position in source descriptor
       
   199     HBufC8* currentBuffer;
       
   200 
       
   201     TInt lastBuffer = iBufferList.Count()-1;
       
   202     if ( lastBuffer < 0 )
       
   203         {
       
   204         // TODO: Make the first block only equal to the size of data we need?
       
   205         // Take some traces to see what happens.
       
   206 
       
   207         // no blocks allocated.  May leave here if we can't get space.
       
   208         currentBuffer = HBufC8::NewLC(iBufferSize);
       
   209         iBufferList.AppendL(currentBuffer);
       
   210         CleanupStack::Pop(currentBuffer);
       
   211         lastBuffer = 0;
       
   212         }
       
   213     else
       
   214         {
       
   215         currentBuffer = iBufferList[lastBuffer];
       
   216         }
       
   217 
       
   218     // here, currentBuffer always points to a buffer we can use.
       
   219     while ( aRemainder )
       
   220         {
       
   221         workingLen = iBufferSize - currentBuffer->Length(); // workingLen = amount of space left in this segment
       
   222         workingLen = (aRemainder > workingLen) ? workingLen : aRemainder;   // workingLen = smaller of (amount of data left in source) or (amount of space left in current segment)
       
   223         if ( workingLen )
       
   224             {
       
   225             // we have some space in this block to store data.
       
   226             TPtr8 ptr(currentBuffer->Des());
       
   227             ptr.Append(aDes.Mid(workingOffset ,workingLen));
       
   228             }
       
   229         aRemainder -= workingLen;   // track how much is consumed
       
   230         workingOffset += workingLen;    // remember where we get the next bit from in the source
       
   231         if ( aRemainder )
       
   232             {
       
   233             // we have more data to store, append another block.  Might result in a leave.
       
   234             currentBuffer = HBufC8::NewLC(iBufferSize);
       
   235             iBufferList.AppendL(currentBuffer);
       
   236             CleanupStack::Pop(currentBuffer);
       
   237             }
       
   238         }
       
   239     // will only exit here if we consumed all data
       
   240     }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CSegmentedHeapBuffer::Length
       
   244 // -----------------------------------------------------------------------------
       
   245 //
       
   246 TInt CSegmentedHeapBuffer::Length()
       
   247     {
       
   248     // all segments are same size except last one
       
   249     TInt len = 0;
       
   250     TInt count = iBufferList.Count();
       
   251     if ( count )
       
   252         {
       
   253         len = iBufferSize * (count - 1);    // all segments are same size except last one
       
   254         len += iBufferList[count-1]->Length();
       
   255         }
       
   256     return len;
       
   257     }
       
   258 
       
   259 // -----------------------------------------------------------------------------
       
   260 // CSegmentedHeapBuffer::SpareCapacity
       
   261 // -----------------------------------------------------------------------------
       
   262 //
       
   263 TInt CSegmentedHeapBuffer::SpareCapacity()
       
   264     {
       
   265     TInt len = 0;
       
   266     TInt count = iBufferList.Count();
       
   267     if ( count )
       
   268         {
       
   269         len = iBufferSize - (iBufferList[count-1]->Length());
       
   270         }
       
   271 
       
   272     // return how much is left in last segment.
       
   273     return len;
       
   274     }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CSegmentedHeapBuffer::Count
       
   278 // -----------------------------------------------------------------------------
       
   279 //
       
   280 TInt CSegmentedHeapBuffer::Count()
       
   281     {
       
   282     return iBufferList.Count(); // number of segments
       
   283     }
       
   284 
       
   285 // -----------------------------------------------------------------------------
       
   286 // CSegmentedHeapBuffer::GetSegmentData
       
   287 // -----------------------------------------------------------------------------
       
   288 //
       
   289 TPtrC8 CSegmentedHeapBuffer::GetSegmentData(TInt& aSegment)
       
   290     {
       
   291     return iBufferList[aSegment++]->Des();
       
   292     }
       
   293 
       
   294 // -----------------------------------------------------------------------------
       
   295 // CSegmentedHeapBuffer::ReleaseSegmentData
       
   296 // -----------------------------------------------------------------------------
       
   297 //
       
   298 void CSegmentedHeapBuffer::ReleaseSegmentData(const TInt aSegment)
       
   299     {
       
   300     HBufC8* buf = iBufferList[aSegment];
       
   301     iBufferList[aSegment] = 0;  // don't want to reshuffle contents
       
   302     delete buf;
       
   303     }
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // CSegmentedHeapBuffer::Compress
       
   307 // -----------------------------------------------------------------------------
       
   308 //
       
   309 void CSegmentedHeapBuffer::Compress()
       
   310     {
       
   311     TInt count = iBufferList.Count();
       
   312     if ( count )
       
   313         {
       
   314         HBufC8* buf = iBufferList[count-1];
       
   315         // first, see if we can shrink by at least one iCompressGranularity
       
   316         if ( iBufferSize - buf->Length() >= iCompressGranularity )
       
   317             {
       
   318             // calculate new size
       
   319             TInt newsize = (iCompressGranularity * (1 + (buf->Length() / iCompressGranularity)));
       
   320             HBufC8 *newbuf = buf->ReAlloc(newsize);
       
   321             // we should be realloc'ing in place since we're shrinking this piece, but you never know.
       
   322             // don't care if realloc operation fails since it will leave original data alone.
       
   323             if ( newbuf )
       
   324                 {
       
   325                 iBufferList[count-1] = newbuf;
       
   326                 }
       
   327             }
       
   328         }
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 //  CSegmentedHeapBuffer::Reset
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 void CSegmentedHeapBuffer::Reset()
       
   336     {
       
   337     iBufferList.ResetAndDestroy();  // call delete on all buffers
       
   338     }
       
   339 
       
   340 // -----------------------------------------------------------------------------
       
   341 // CSegmentedHeapBuffer::CSegmentedHeapBuffer
       
   342 // -----------------------------------------------------------------------------
       
   343 //
       
   344 CSegmentedHeapBuffer::CSegmentedHeapBuffer(TInt aBufferSize, TInt aCompressGranularity) : iBufferSize(aBufferSize), iCompressGranularity(aCompressGranularity)
       
   345     {
       
   346     }
       
   347 
       
   348 // -----------------------------------------------------------------------------
       
   349 // CHttpCacheWriteTimeout::CHttpCacheWriteTimeout
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 CHttpCacheWriteTimeout::CHttpCacheWriteTimeout( const TInt aTimeout )
       
   353     : CActive(EPriorityStandard),
       
   354       iTimeout(aTimeout) // Standard priority
       
   355     {
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // CHttpCacheWriteTimeout::NewLC
       
   360 // -----------------------------------------------------------------------------
       
   361 //
       
   362 CHttpCacheWriteTimeout* CHttpCacheWriteTimeout::NewLC(const TInt aTimeout)
       
   363     {
       
   364     CHttpCacheWriteTimeout* self = new ( ELeave ) CHttpCacheWriteTimeout(aTimeout);
       
   365     CleanupStack::PushL(self);
       
   366     self->ConstructL();
       
   367     return self;
       
   368     }
       
   369 
       
   370 // -----------------------------------------------------------------------------
       
   371 // CHttpCacheWriteTimeout::NewL
       
   372 // -----------------------------------------------------------------------------
       
   373 //
       
   374 CHttpCacheWriteTimeout* CHttpCacheWriteTimeout::NewL(const TInt aTimeout)
       
   375     {
       
   376     CHttpCacheWriteTimeout* self = CHttpCacheWriteTimeout::NewLC(aTimeout);
       
   377     CleanupStack::Pop(); // self;
       
   378     return self;
       
   379     }
       
   380 
       
   381 // -----------------------------------------------------------------------------
       
   382 // CHttpCacheWriteTimeout::ConstructL
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 void CHttpCacheWriteTimeout::ConstructL()
       
   386     {
       
   387     User::LeaveIfError(iTimer.CreateLocal()); // Initialize timer
       
   388     CActiveScheduler::Add(this); // Add to scheduler
       
   389     }
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // CHttpCacheWriteTimeout::~CHttpCacheWriteTimeout
       
   393 // -----------------------------------------------------------------------------
       
   394 //
       
   395 CHttpCacheWriteTimeout::~CHttpCacheWriteTimeout()
       
   396     {
       
   397     Cancel(); // Cancel any request, if outstanding
       
   398     iTimer.Close(); // Destroy the RTimer object
       
   399     // Delete instance variables if any
       
   400     }
       
   401 
       
   402 // -----------------------------------------------------------------------------
       
   403 // CHttpCacheWriteTimeout::DoCancel
       
   404 // -----------------------------------------------------------------------------
       
   405 //
       
   406 void CHttpCacheWriteTimeout::DoCancel()
       
   407     {
       
   408     iTimer.Cancel();
       
   409     }
       
   410 
       
   411 // -----------------------------------------------------------------------------
       
   412 // CHttpCacheWriteTimeout::Start
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 void CHttpCacheWriteTimeout::Start(TCallBack aCallbackFn, TAny *aToken)
       
   416     {
       
   417     Cancel(); // Cancel any request, just to be sure
       
   418 
       
   419     iToken = aToken;
       
   420     iCallbackFn = aCallbackFn;
       
   421 
       
   422     iTimer.After(iStatus, iTimeout); // Set for later
       
   423     SetActive(); // Tell scheduler a request is active
       
   424     }
       
   425 
       
   426 // -----------------------------------------------------------------------------
       
   427 // CHttpCacheWriteTimeout::RunL
       
   428 // -----------------------------------------------------------------------------
       
   429 //
       
   430 void CHttpCacheWriteTimeout::RunL()
       
   431     {
       
   432     iCallbackFn.iFunction(iToken);
       
   433     }
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // CHttpCacheWriteTimeout::RunError
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 TInt CHttpCacheWriteTimeout::RunError(TInt aError)
       
   440     {
       
   441     return aError;
       
   442     }
       
   443 
       
   444 //  End of File