omadrm/drmplugins/drmfilter/src/HTTPFilterDRMDataSupplier.cpp
changeset 0 95b198f216e5
child 11 e16d72588c28
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2  * Copyright (c) 2006-2009 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 "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:
       
    15  *
       
    16  */
       
    17 
       
    18 #include <http/rhttptransaction.h>
       
    19 #include <barsc.h>
       
    20 #include <drmcommon.h>
       
    21 #include <f32file.h>
       
    22 #include <s32buf.h>
       
    23 #include <drmmessageparser.h>
       
    24 #include <caf/caf.h>
       
    25 #include <oma2agent.h>
       
    26 
       
    27 #include "httpfilterdrmdatasupplier.h"
       
    28 #include "httpfilterdrm.h"
       
    29 
       
    30 //------------------------------------------------------------------------
       
    31 
       
    32 const TInt KMinContentSizeToGetTheURI = 520;
       
    33 const TInt KDefaultSize( 2048 );
       
    34 const TInt KWholeDataPart( -1 );
       
    35 
       
    36 // ============================ MEMBER FUNCTIONS ===============================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CHTTPFilterDRMDataSupplier::NewL
       
    40 // Two-phase constructor
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CHTTPFilterDRMDataSupplier* CHTTPFilterDRMDataSupplier::NewL( TInt aTransId,
       
    44     MHTTPDataSupplier* iDataBody, CHTTPFilterDRM* aOwner )
       
    45     {
       
    46     CHTTPFilterDRMDataSupplier* self =
       
    47         new ( ELeave ) CHTTPFilterDRMDataSupplier( aTransId, iDataBody,
       
    48             aOwner );
       
    49 
       
    50     CleanupStack::PushL( self );
       
    51     self->ConstructL( KDefaultSize );
       
    52     CleanupStack::Pop( self );
       
    53     return self;
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CHTTPFilterDRMDataSupplier::NewL
       
    58 // Two-phase constructor, CFM
       
    59 // -----------------------------------------------------------------------------
       
    60 //	
       
    61 CHTTPFilterDRMDataSupplier* CHTTPFilterDRMDataSupplier::NewL( TInt aTransId,
       
    62     MHTTPDataSupplier* iDataBody, TProcessedContentType aType,
       
    63     CHTTPFilterDRM* aOwner )
       
    64     {
       
    65     CHTTPFilterDRMDataSupplier* self =
       
    66         new ( ELeave ) CHTTPFilterDRMDataSupplier( aTransId, iDataBody,
       
    67             aOwner );
       
    68     CleanupStack::PushL( self );
       
    69     self->ConstructL( KDefaultSize, aType );
       
    70     CleanupStack::Pop( self );
       
    71     return self;
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CHTTPFilterDRMDataSupplier::CHTTPFilterDRMDataSupplier
       
    76 // constructor
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CHTTPFilterDRMDataSupplier::CHTTPFilterDRMDataSupplier( TInt aTransId,
       
    80     MHTTPDataSupplier* iDataBody, CHTTPFilterDRM* aOwner ) :
       
    81     iTransId( aTransId ), iBufPtr( 0, 0 ), iPHData( iDataBody ), iSendReady(
       
    82         EFalse ), iOwner( aOwner )
       
    83     {
       
    84     iDRMMessageParser = 0;
       
    85     iPrevPos = 0;
       
    86     iMemBuf = 0;
       
    87     iDataPartSize = KWholeDataPart;
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CHTTPFilterDRMDataSupplier::ConstructL
       
    92 // Data allocation constructor, which leaves
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 void CHTTPFilterDRMDataSupplier::ConstructL( TInt aSize )
       
    96     {
       
    97     // create the output buffer
       
    98     iBuf = HBufC8::NewMaxL( aSize );
       
    99 
       
   100     iBufPtr.Set( iBuf->Des() );
       
   101     iBufPtr.SetLength( 0 );
       
   102 
       
   103     // setup the memory buffer
       
   104     iMemBuf = TDRMMemBuf::NewL( aSize );
       
   105 
       
   106     // create the DRM client and the writable memory stream
       
   107     iDRMMessageParser = CDRMMessageParser::NewL();
       
   108 
       
   109     Attach( iMemBuf );
       
   110 
       
   111     iDRMMessageParser->InitializeMessageParserL( *this );
       
   112 
       
   113     }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // CHTTPFilterDRMDataSupplier::ConstructL
       
   117 // Data allocation constructor, which leaves, CFM
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 void CHTTPFilterDRMDataSupplier::ConstructL( TInt aSize,
       
   121     TProcessedContentType /*aType*/)
       
   122     {
       
   123     // create the output buffer
       
   124     iBuf = HBufC8::NewMaxL( aSize );
       
   125     iBufPtr.Set( iBuf->Des() );
       
   126     iBufPtr.SetLength( 0 );
       
   127 
       
   128     // setup the memory buffer
       
   129     iMemBuf = TDRMMemBuf::NewL( aSize );
       
   130 
       
   131     iDRMOma1DcfCreator = COma1DcfCreator::NewL();
       
   132     Attach( iMemBuf );
       
   133     }
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CHTTPFilterDRMDataSupplier::~CHTTPFilterDRMDataSupplier()
       
   137 // Destructor
       
   138 // -----------------------------------------------------------------------------
       
   139 //
       
   140 CHTTPFilterDRMDataSupplier::~CHTTPFilterDRMDataSupplier()
       
   141     {
       
   142 
       
   143     // First make sure that we have completed everything, before we delete
       
   144     // Anything essential
       
   145     if ( !iSendReady ) // the destructor is called by other filters
       
   146         {
       
   147         if ( iDRMMessageParser )
       
   148             {
       
   149             TRAP_IGNORE( iDRMMessageParser->FinalizeMessageParserL() );
       
   150             }
       
   151         }
       
   152 
       
   153     if ( iDRMMessageParser )
       
   154         {
       
   155         delete iDRMMessageParser;
       
   156         iDRMMessageParser = NULL;
       
   157         }
       
   158 
       
   159     if ( iMemBuf )
       
   160         {
       
   161         delete iMemBuf;
       
   162         iMemBuf = NULL;
       
   163         }
       
   164 
       
   165     // This used to be deleted first, but this of course caused the finalize to fail
       
   166     if ( iBuf )
       
   167         {
       
   168         delete iBuf;
       
   169         iBuf = NULL;
       
   170         }
       
   171 
       
   172     iPHData = 0;
       
   173 
       
   174     if ( iContentMimeType )
       
   175         {
       
   176         delete iContentMimeType;
       
   177         iContentMimeType = NULL;
       
   178         }
       
   179 
       
   180     if ( iDRMOma1DcfCreator )
       
   181         {
       
   182         delete iDRMOma1DcfCreator;
       
   183         iDRMOma1DcfCreator = NULL;
       
   184         }
       
   185     }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CHTTPFilterDRMDataSupplier::AppendDataL
       
   189 // Append a bulk of data into the supplier's buffer
       
   190 // reallocation is needed when buffer is not big enough
       
   191 // -----------------------------------------------------------------------------
       
   192 //
       
   193 void CHTTPFilterDRMDataSupplier::AppendDataL( const TDesC8& aDataPart )
       
   194     {
       
   195     TInt curLen = iBufPtr.Length();
       
   196     TInt reqLen = curLen + aDataPart.Length();
       
   197 
       
   198     if ( reqLen > iBufPtr.MaxLength() )
       
   199         {
       
   200         TRAPD( error, ( iBuf = iBuf->ReAllocL( reqLen + aDataPart.Length() ) ) ); // realloc a bit more data, this should not happen often
       
   201         if ( error != KErrNone )
       
   202             User::Leave( KErrNoMemory );
       
   203 
       
   204         iBufPtr.Set( iBuf->Des() );
       
   205         iBufPtr.SetLength( curLen );
       
   206         }
       
   207     iBufPtr.Append( aDataPart );
       
   208     }
       
   209 
       
   210 // -----------------------------------------------------------------------------
       
   211 // CHTTPFilterDRMDataSupplier::EncryptContentL
       
   212 // encrypt the content with DRM client
       
   213 // -----------------------------------------------------------------------------
       
   214 //
       
   215 void CHTTPFilterDRMDataSupplier::ProcessDataPartL()
       
   216     {
       
   217     // get the data part
       
   218     TPtrC8 dataPart;
       
   219     TBool lastChunk = iPHData->GetNextDataPart( dataPart );
       
   220 
       
   221     /** Support for Hutchinson's content protection scheme, CFM
       
   222      *
       
   223      */
       
   224     // encrypt the data
       
   225     if ( iProcessedContentType == EStandardDRMContent )
       
   226         {
       
   227         TRAPD( err, iDRMMessageParser->ProcessMessageDataL( dataPart ) );
       
   228 
       
   229         // error happens
       
   230         if ( err != KErrNone )
       
   231             {
       
   232             iDRMMessageParser->FinalizeMessageParserL();
       
   233             User::Leave( err );
       
   234             }
       
   235 
       
   236         if ( lastChunk )
       
   237             {
       
   238             iSendReady = ETrue;
       
   239             iDRMMessageParser->FinalizeMessageParserL();
       
   240             }
       
   241         }
       
   242     else if ( iProcessedContentType
       
   243         == EHutchinsonCFMWithRingingToneNoFirstChunk )
       
   244         {
       
   245         //create rights
       
   246         CDRMRights* rights = CDRMRights::NewL();
       
   247         CleanupStack::PushL( rights );
       
   248 
       
   249         // Asset contains the content id
       
   250         // DrmAsset.h
       
   251         CDRMAsset* asset = CDRMAsset::NewLC();
       
   252         _LIT8(KContentURI, "flk:flkS60_3_0_Hutchinson_2005");
       
   253         asset->iUid = KContentURI().AllocL(); // This will be freed by the assets destructor
       
   254 
       
   255         // Set the asset to the rights class, it will duplicate the asset
       
   256         rights->SetAssetL( *asset );
       
   257         CleanupStack::PopAndDestroy( asset ); // Asset
       
   258 
       
   259         // DRMPermission.h
       
   260         CDRMPermission* permission = CDRMPermission::NewLC();
       
   261 
       
   262         // DRMConstraint.h
       
   263         // DRMTypes.h
       
   264         permission->iPlay = CDRMConstraint::NewL();
       
   265         permission->iDisplay = CDRMConstraint::NewL();
       
   266         permission->iExecute = CDRMConstraint::NewL();
       
   267         permission->iPrint = CDRMConstraint::NewL();
       
   268 
       
   269         permission->iAvailableRights = ERightsPlay | ERightsDisplay
       
   270             | ERightsExecute | ERightsPrint;
       
   271 
       
   272         permission->iRightsObjectVersion.iVersionMain = 1; // major version for Oma 1 Rights Objects		
       
   273 
       
   274         // "ringtone=no" present 
       
   275         permission->iInfoBits = ENoRingingTone;
       
   276 
       
   277         // Set the permission to the rights class, it will duplicate the permission
       
   278         rights->SetPermissionL( *permission );
       
   279 
       
   280         CleanupStack::PopAndDestroy( permission ); // Permission
       
   281 
       
   282         //initializing
       
   283         iDRMOma1DcfCreator->EncryptInitializeL( *this,
       
   284             iContentMimeType->Des(), rights );
       
   285         //process current chunk
       
   286         TRAPD(err, iDRMOma1DcfCreator->EncryptUpdateL(dataPart));
       
   287         if ( err )
       
   288             {
       
   289             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   290             User::Leave( err );
       
   291             }
       
   292 
       
   293         // if there is only one chunk
       
   294         if ( lastChunk )
       
   295             {
       
   296             iSendReady = ETrue;
       
   297             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   298             }
       
   299 
       
   300         CleanupStack::PopAndDestroy( rights );
       
   301         iProcessedContentType = EHutchinsonCFMNoContinuation;
       
   302         }
       
   303     else if ( iProcessedContentType == EHutchinsonCFMNoFirstChunk )
       
   304         {
       
   305         //initializing
       
   306         iDRMOma1DcfCreator->EncryptInitializeL( *this,
       
   307             iContentMimeType->Des(), NULL);
       
   308         //process current chunk
       
   309         TRAPD(err, iDRMOma1DcfCreator->EncryptUpdateL(dataPart));
       
   310         if ( err )
       
   311             {
       
   312             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   313             User::Leave( err );
       
   314             }
       
   315 
       
   316         // if there is only one chunk
       
   317         if ( lastChunk )
       
   318             {
       
   319             iSendReady = ETrue;
       
   320             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   321             }
       
   322         iProcessedContentType = EHutchinsonCFMNoContinuation;
       
   323         }
       
   324     else if ( iProcessedContentType == EHutchinsonCFMNoContinuation )
       
   325         {
       
   326         TRAPD(err, iDRMOma1DcfCreator->EncryptUpdateL(dataPart));
       
   327         if ( err )
       
   328             {
       
   329             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   330             User::Leave( err );
       
   331             }
       
   332         if ( lastChunk )
       
   333             {
       
   334             iSendReady = ETrue;
       
   335             iDRMOma1DcfCreator->EncryptFinalizeL();
       
   336             }
       
   337         }
       
   338     else
       
   339         {
       
   340         User::Leave( KErrUnknown );
       
   341         }
       
   342     iPHData->ReleaseData();
       
   343     }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CHTTPFilterDRMDataSupplier::GetNextDataPart
       
   347 // virtual methods from MHTTPDataSupplier
       
   348 // -----------------------------------------------------------------------------
       
   349 //
       
   350 TBool CHTTPFilterDRMDataSupplier::GetNextDataPart( TPtrC8& aDataPart )
       
   351     {
       
   352 
       
   353     if ( iDataPartSize == KWholeDataPart )
       
   354         {
       
   355         aDataPart.Set( iMemBuf->iBuf->GetPtr() );
       
   356         iDataPartSize = aDataPart.Length();
       
   357         }
       
   358     else
       
   359         {
       
   360         aDataPart.Set( iMemBuf->iBuf->GetPtr().Left( iDataPartSize ) );
       
   361         }
       
   362 
       
   363     return ( iDataPartSize == KWholeDataPart ) ? iSendReady : EFalse;
       
   364     }
       
   365 
       
   366 // -----------------------------------------------------------------------------
       
   367 // CHTTPFilterDRMDataSupplier::ReleaseData
       
   368 // virtual methods from MHTTPDataSupplier
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 void CHTTPFilterDRMDataSupplier::ReleaseData()
       
   372     {
       
   373     if ( iDataPartSize == KWholeDataPart )
       
   374         {
       
   375         TRAP_IGNORE( Sink()->SeekL( MStreamBuf::EWrite, TStreamPos(0) ) );
       
   376         if ( iSendReady )
       
   377             {
       
   378             iOwner->DeleteDataSupplier( iTransId );
       
   379             }
       
   380         }
       
   381     else
       
   382         {
       
   383         //Remove only consumed data part
       
   384         HBufC8* b( iMemBuf->iBuf->GetPtr().Mid( iDataPartSize ).AllocLC() );
       
   385         TRAP_IGNORE( Sink()->SeekL( MStreamBuf::EWrite, TStreamPos(0) ) );
       
   386         // Warning: assuming sink is big enough for write of whole b.
       
   387         TRAP_IGNORE( Sink()->WriteL( b->Ptr(), b->Length() ) );
       
   388         CleanupStack::PopAndDestroy( b );
       
   389         // Update data part size to available data.
       
   390         iDataPartSize = KWholeDataPart;
       
   391         }
       
   392     }
       
   393 
       
   394 // -----------------------------------------------------------------------------
       
   395 // CHTTPFilterDRMDataSupplier::OverallDataSize
       
   396 // virtual methods from MHTTPDataSupplier
       
   397 // -----------------------------------------------------------------------------
       
   398 //
       
   399 TInt CHTTPFilterDRMDataSupplier::OverallDataSize()
       
   400     {
       
   401     return KErrNotFound;
       
   402     }
       
   403 
       
   404 // -----------------------------------------------------------------------------
       
   405 // CHTTPFilterDRMDataSupplier::Reset
       
   406 // virtual methods from MHTTPDataSupplier
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 TInt CHTTPFilterDRMDataSupplier::Reset()
       
   410     {
       
   411     return KErrNone;
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CHTTPFilterDRMDataSupplier::SetContentMimeTypeL
       
   416 // Sets the MIME type of comming content - used for ringingtone functionality
       
   417 // Caller does not care about freeing this buffer, CFM
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 void CHTTPFilterDRMDataSupplier::SetContentMimeTypeL( const TDesC8& aMimeType )
       
   421     {
       
   422     //in case someone call this function more than once
       
   423     delete iContentMimeType;
       
   424     iContentMimeType = NULL;
       
   425 
       
   426     iContentMimeType = aMimeType.AllocL();
       
   427     }
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // CHTTPFilterDRMDataSupplier::SetEstimatedArrivalTime
       
   431 // Sets the estimated arrival time, the x-oma-drm-separate-delivery header
       
   432 //-----------------------------------------------------------------------------
       
   433 //
       
   434 
       
   435 #ifdef __DRM_FULL
       
   436 void CHTTPFilterDRMDataSupplier::SetEstimatedArrivalTime( TInt aXOmaHeaderVal )
       
   437     {
       
   438     // get the data part
       
   439     ContentAccess::CManager* manager = NULL;
       
   440     ContentAccess::TAgent agent;
       
   441     TRequestStatus status;
       
   442     TInt r = KErrNone;
       
   443     DRMCommon::TContentProtection protection;
       
   444     HBufC8* MIMEType = NULL;
       
   445     HBufC8* contentURI = NULL;
       
   446     HBufC8* xomaData = NULL;
       
   447     TUint dataLength;
       
   448     TPtrC8 dataPart;
       
   449     DRMCommon* drmCommon = NULL;
       
   450 
       
   451         TRAP(r, drmCommon = DRMCommon::NewL());
       
   452     if ( r )
       
   453         {
       
   454         return;
       
   455         }
       
   456 
       
   457     r = drmCommon->Connect();
       
   458     if ( r )
       
   459         {
       
   460         delete drmCommon;
       
   461         return;
       
   462         }
       
   463 
       
   464     iPHData->GetNextDataPart( dataPart );
       
   465 
       
   466     //in case the chunk is too short engine would panic
       
   467     if ( dataPart.Length() < KMinContentSizeToGetTheURI )
       
   468         return;
       
   469 
       
   470         // Find the caf agent and create manager
       
   471         TRAP( r, manager = GetCafDataL( agent ));
       
   472 
       
   473     // if an error occurs, return
       
   474     if ( r )
       
   475         {
       
   476         delete drmCommon;
       
   477         return;
       
   478         }
       
   479 
       
   480     // Get the content info, if it fails dont do anything
       
   481     if ( drmCommon->GetContentInfo( dataPart, protection, MIMEType,
       
   482         contentURI, dataLength ) == DRMCommon::EOk && protection
       
   483         != DRMCommon::ENoDCFFile )
       
   484         {
       
   485         // Create a buffer large enough for the time and uri
       
   486         xomaData = HBufC8::NewMax( sizeof(TInt) + contentURI->Size() );
       
   487 
       
   488         // if the creation fails free memory and return
       
   489         if ( !xomaData )
       
   490             {
       
   491             delete MIMEType;
       
   492             delete contentURI;
       
   493             delete manager;
       
   494             delete drmCommon;
       
   495             return;
       
   496             }
       
   497 
       
   498         // Copy the value of the xoma header:
       
   499         Mem::Copy( const_cast<TUint8*> ( xomaData->Ptr() ), &aXOmaHeaderVal,
       
   500             sizeof(TInt) );
       
   501 
       
   502         // Copy the value of the uri:
       
   503         Mem::Copy( const_cast<TUint8*> ( xomaData->Ptr() ) + sizeof(TInt),
       
   504             contentURI->Ptr(), contentURI->Size() );
       
   505 
       
   506         TPtr8 temp( NULL, 0, 0 );
       
   507         TPtr8 buffer( xomaData->Des() );
       
   508 
       
   509         // ignore any error, we couldn't do anything about it anyway
       
   510         r = manager->AgentSpecificCommand( agent,
       
   511             ContentAccess::ESetPendingRightsETA, buffer, temp );
       
   512         }
       
   513     delete MIMEType;
       
   514     delete contentURI;
       
   515     delete manager;
       
   516     delete xomaData;
       
   517     delete drmCommon;
       
   518     }
       
   519 #else
       
   520 void CHTTPFilterDRMDataSupplier::SetEstimatedArrivalTime(TInt /*aXOmaHeaderVal*/)
       
   521     {
       
   522     }
       
   523 #endif
       
   524 
       
   525 // -----------------------------------------------------------------------------
       
   526 // CHTTPFilterDRMDataSupplier::SetContentMimeTypeL
       
   527 // Sets the MIME type of comming content - used for ringingtone functionality
       
   528 // Caller does not care about freeing this buffer
       
   529 // -----------------------------------------------------------------------------
       
   530 //
       
   531 ContentAccess::CManager* CHTTPFilterDRMDataSupplier::GetCafDataL(
       
   532     TAgent& aAgent )
       
   533     {
       
   534     TPtr8 ptr( NULL, 0, 0 );
       
   535     RArray<TAgent> agents;
       
   536     TRequestStatus status;
       
   537     TInt i;
       
   538 
       
   539     CleanupClosePushL( agents );
       
   540     CManager* manager = CManager::NewLC();
       
   541 
       
   542     manager->ListAgentsL( agents );
       
   543 
       
   544     for ( i = 0; i < agents.Count(); i++ )
       
   545         {
       
   546         if ( agents[i].Name().Compare( KOmaDrm2AgentName ) == 0 )
       
   547             {
       
   548             aAgent = agents[i];
       
   549             break;
       
   550             }
       
   551         }
       
   552     CleanupStack::Pop( manager );
       
   553     CleanupStack::PopAndDestroy( &agents );        
       
   554     return manager;
       
   555     }
       
   556 
       
   557 //=============================================================================
       
   558 // TDRMMemBuf functions
       
   559 //=============================================================================
       
   560 TDRMMemBuf* TDRMMemBuf::NewL( TInt aLength )
       
   561     {
       
   562     TDRMMemBuf* self = new ( ELeave ) TDRMMemBuf;
       
   563     CleanupStack::PushL( self );
       
   564     self->ConstructL( aLength );
       
   565     CleanupStack::Pop( self );
       
   566     return self;
       
   567     }
       
   568 
       
   569 TDRMMemBuf::~TDRMMemBuf()
       
   570     {
       
   571     delete iBuf;
       
   572     iBuf = 0;
       
   573     }
       
   574 
       
   575 void TDRMMemBuf::ConstructL( TInt aLength )
       
   576     {
       
   577     // create the buffer and set it as intermidiate
       
   578     iBuf = HeapArray8::NewMaxL( aLength );
       
   579     TUint8* base = ( TUint8* )( iBuf->GetPtr().Ptr() );
       
   580     Set( base, base + aLength );
       
   581     }
       
   582 
       
   583 void TDRMMemBuf::DoWriteL( const TAny* aPtr, TInt aLength )
       
   584     {
       
   585     //make sure there is enough room for writing
       
   586     if ( iBuf->Append( ( TUint8* )aPtr, aLength ) )
       
   587         {
       
   588         // re-allocation happened
       
   589         TUint8* base = ( TUint8* )( iBuf->GetPtr().Ptr() );
       
   590         Set( base, base + iBuf->GetPtr().MaxLength() );
       
   591         }
       
   592     }
       
   593 
       
   594 TStreamPos TDRMMemBuf::DoSeekL( TMark aMark, TStreamLocation aLocation,
       
   595     TInt anOffset )
       
   596     {
       
   597     if ( aMark == MStreamBuf::EWrite && aLocation == EStreamBeginning )
       
   598         iBuf->GetPtr().SetLength( anOffset );
       
   599 
       
   600     return TMemBuf::DoSeekL( aMark, aLocation, anOffset );
       
   601     }
       
   602 
       
   603 //=============================================================================
       
   604 // HeapArray functions
       
   605 //=============================================================================
       
   606 HeapArray8* HeapArray8::NewMaxL( TInt max_ )
       
   607     {
       
   608     HeapArray8* self = new ( ELeave ) HeapArray8();
       
   609     CleanupStack::PushL( self );
       
   610     self->ConstructL( max_ );
       
   611     CleanupStack::Pop( self );
       
   612     return self;
       
   613     }
       
   614 
       
   615 void HeapArray8::ConstructL( TInt max_ )
       
   616     {
       
   617     buf = HBufC8::NewMaxL( max_ );
       
   618     ptr.Set( buf->Des() );
       
   619     ptr.SetLength( 0 );
       
   620     }
       
   621 
       
   622 HeapArray8::HeapArray8() :
       
   623     buf( 0 ), ptr( 0, 0 )
       
   624     {
       
   625     }
       
   626 
       
   627 HeapArray8::~HeapArray8()
       
   628     {
       
   629     delete buf;
       
   630     }
       
   631 
       
   632 TBool HeapArray8::Append( const TDesC8 &src_ )
       
   633     {
       
   634     return Insert( ptr.Length(), src_ );
       
   635     }
       
   636 
       
   637 TBool HeapArray8::Insert( TInt index, const TDesC8 &src_ )
       
   638     {
       
   639     TInt insertLen = src_.Length();
       
   640     TBool bRellocated = EFalse;
       
   641 
       
   642     if ( ptr.Length() + insertLen > ptr.MaxLength() )
       
   643         {
       
   644         TInt oLen = ptr.Length();
       
   645         buf = buf->ReAlloc( ptr.Length() + insertLen * 2 );
       
   646         ptr.Set( buf->Des() );
       
   647         ptr.SetLength( oLen );
       
   648         bRellocated = ETrue;
       
   649         }
       
   650     ptr.Insert( index, src_ );
       
   651     return bRellocated;
       
   652     }
       
   653 
       
   654 TBool HeapArray8::Insert( TInt index, const TUint8 *src_, TInt insertLen )
       
   655     {
       
   656     TPtrC8 ptr( src_, insertLen );
       
   657     return Insert( index, ptr );
       
   658     }
       
   659 
       
   660 TBool HeapArray8::Append( const TUint8* src_, TInt len_ )
       
   661     {
       
   662     TPtrC8 p( src_, len_ );
       
   663     return Insert( ptr.Length(), p );
       
   664     }