omadrm/drmengine/dm/src/DRMMessageParser.cpp
changeset 23 493788a4a8a4
parent 0 95b198f216e5
child 32 457cd4423b8c
equal deleted inserted replaced
5:79d62d1d7957 23:493788a4a8a4
    24 #include <caf/caftypes.h>
    24 #include <caf/caftypes.h>
    25 #include <wspdecoder.h>
    25 #include <wspdecoder.h>
    26 #include <wspencoder.h>
    26 #include <wspencoder.h>
    27 
    27 
    28 #ifdef RD_MULTIPLE_DRIVE
    28 #ifdef RD_MULTIPLE_DRIVE
    29 #include <DriveInfo.h>
    29 #include <driveinfo.h>
    30 #endif
    30 #endif
    31 
    31 
    32 #include "DrmRights.h"
    32 #include "DRMRights.h"
    33 #include "Oma1DcfCreator.h"
    33 #include "Oma1DcfCreator.h"
    34 #include "b64.h"
    34 #include "b64.h"
    35 #include "DRMMessageParser.h"
    35 #include "DRMMessageParser.h"
    36 #include "DRMRightsParser.h"
    36 #include "DrmRightsParser.h"
    37 #include "DRMRightsClient.h"
    37 #include "DRMRightsClient.h"
    38 #include "DrmKeyStorage.h"
    38 #include "DrmKeyStorage.h"
    39 
    39 
    40 
    40 
    41 // EXTERNAL DATA STRUCTURES
    41 // EXTERNAL DATA STRUCTURES
    42 // EXTERNAL FUNCTION PROTOTYPES  
    42 // EXTERNAL FUNCTION PROTOTYPES
    43 // CONSTANTS
    43 // CONSTANTS
    44 // MACROS
    44 // MACROS
    45 // LOCAL CONSTANTS AND MACROS
    45 // LOCAL CONSTANTS AND MACROS
    46 LOCAL_C const TInt KDefaultInputBufferSize = 2048;
    46 LOCAL_C const TInt KDefaultInputBufferSize = 2048;
    47 LOCAL_C const TInt KDRMMessageMalformed = KErrGeneral;
    47 LOCAL_C const TInt KDRMMessageMalformed = KErrGeneral;
    52 _LIT8( KFLPrefix, "flk:");
    52 _LIT8( KFLPrefix, "flk:");
    53 LOCAL_C const TInt KFLKPrefixLength = 4;
    53 LOCAL_C const TInt KFLKPrefixLength = 4;
    54 
    54 
    55 _LIT8( KFLSuffix, "@localhost");
    55 _LIT8( KFLSuffix, "@localhost");
    56 LOCAL_C const TUint8 KCDContentIDLength = 25; // 4 + 11 + 10
    56 LOCAL_C const TUint8 KCDContentIDLength = 25; // 4 + 11 + 10
    57 LOCAL_C const TUint8 KCDPlainIDLength = 11; 
    57 LOCAL_C const TUint8 KCDPlainIDLength = 11;
    58 
    58 
    59 LOCAL_C const TInt KInputBufferSize = 2048;
    59 LOCAL_C const TInt KInputBufferSize = 2048;
    60 LOCAL_C const TInt KBoundaryMarkLength = 2;
    60 LOCAL_C const TInt KBoundaryMarkLength = 2;
    61 
    61 
    62 LOCAL_C const TUint KInitialDCFBufferSize = 4096;
    62 LOCAL_C const TUint KInitialDCFBufferSize = 4096;
   106 struct TDeleteFileData
   106 struct TDeleteFileData
   107     {
   107     {
   108     RFs aFs;
   108     RFs aFs;
   109     TFileName aName;
   109     TFileName aName;
   110     };
   110     };
   111     
   111 
   112 // LOCAL FUNCTION PROTOTYPES
   112 // LOCAL FUNCTION PROTOTYPES
   113 LOCAL_C void DoResetAndDestroy( TAny* aPtr );
   113 LOCAL_C void DoResetAndDestroy( TAny* aPtr );
   114 LOCAL_C void DoResetAndDestroy2( TAny* aPtr );
   114 LOCAL_C void DoResetAndDestroy2( TAny* aPtr );
   115 LOCAL_C void DoDeleteFile( TAny* aPtr );
   115 LOCAL_C void DoDeleteFile( TAny* aPtr );
   116 LOCAL_C void ConvertPermissionL( CDRMRights*& aRights,
   116 LOCAL_C void ConvertPermissionL( CDRMRights*& aRights,
   124 // Does ResetAndDestroy() to given RPointerArray< CDRMRights >
   124 // Does ResetAndDestroy() to given RPointerArray< CDRMRights >
   125 // -----------------------------------------------------------------------------
   125 // -----------------------------------------------------------------------------
   126 void DoResetAndDestroy( TAny* aPtr )
   126 void DoResetAndDestroy( TAny* aPtr )
   127     {
   127     {
   128     __ASSERT_DEBUG( aPtr, User::Invariant() );
   128     __ASSERT_DEBUG( aPtr, User::Invariant() );
   129     
   129 
   130     reinterpret_cast< RPointerArray< CDRMRights >* >( aPtr )->ResetAndDestroy();
   130     reinterpret_cast< RPointerArray< CDRMRights >* >( aPtr )->ResetAndDestroy();
   131     }
   131     }
   132 
   132 
   133 void DoResetAndDestroy2( TAny* aPtr )
   133 void DoResetAndDestroy2( TAny* aPtr )
   134     {
   134     {
   135     __ASSERT_DEBUG( aPtr, User::Invariant() );
   135     __ASSERT_DEBUG( aPtr, User::Invariant() );
   136     
   136 
   137     reinterpret_cast< RPointerArray< CDRMPermission >* >( aPtr )->ResetAndDestroy();
   137     reinterpret_cast< RPointerArray< CDRMPermission >* >( aPtr )->ResetAndDestroy();
   138     }
   138     }
   139 // -----------------------------------------------------------------------------
   139 // -----------------------------------------------------------------------------
   140 // DoDeleteFile
   140 // DoDeleteFile
   141 // Delete the file presented by TDeleteFileData pointer.
   141 // Delete the file presented by TDeleteFileData pointer.
   151                          CDRMPermission& aPermission,
   151                          CDRMPermission& aPermission,
   152                          const TDesC8& aURI )
   152                          const TDesC8& aURI )
   153     {
   153     {
   154     CDRMAsset* asset( NULL );
   154     CDRMAsset* asset( NULL );
   155     CDRMRights* rights( NULL );
   155     CDRMRights* rights( NULL );
   156     
   156 
   157     aRights = NULL;
   157     aRights = NULL;
   158     
   158 
   159     rights = CDRMRights::NewL();
   159     rights = CDRMRights::NewL();
   160     CleanupStack::PushL( rights );
   160     CleanupStack::PushL( rights );
   161     
   161 
   162     asset = CDRMAsset::NewL();
   162     asset = CDRMAsset::NewL();
   163     CleanupStack::PushL( asset );
   163     CleanupStack::PushL( asset );
   164     
   164 
   165     asset->iUid = aURI.AllocL();
   165     asset->iUid = aURI.AllocL();
   166     
   166 
   167     if ( aPermission.iParentUID )
   167     if ( aPermission.iParentUID )
   168         {
   168         {
   169         asset->iParentRights = aPermission.iParentUID->AllocL();
   169         asset->iParentRights = aPermission.iParentUID->AllocL();
   170         }
   170         }
   171     
   171 
   172     rights->SetPermissionL( aPermission );
   172     rights->SetPermissionL( aPermission );
   173     rights->SetAssetL( *asset );
   173     rights->SetAssetL( *asset );
   174     
   174 
   175     CleanupStack::PopAndDestroy(); // asset
   175     CleanupStack::PopAndDestroy(); // asset
   176     CleanupStack::Pop(), // rights
   176     CleanupStack::Pop(), // rights
   177     
   177 
   178     aRights = rights;
   178     aRights = rights;
   179     }
   179     }
   180 
   180 
   181 // ============================ MEMBER FUNCTIONS ===============================
   181 // ============================ MEMBER FUNCTIONS ===============================
   182 // -----------------------------------------------------------------------------
   182 // -----------------------------------------------------------------------------
   185 // -----------------------------------------------------------------------------
   185 // -----------------------------------------------------------------------------
   186 //
   186 //
   187 EXPORT_C CDRMMessageParser* CDRMMessageParser::NewL( void )
   187 EXPORT_C CDRMMessageParser* CDRMMessageParser::NewL( void )
   188     {
   188     {
   189     CDRMMessageParser* self = new( ELeave ) CDRMMessageParser();
   189     CDRMMessageParser* self = new( ELeave ) CDRMMessageParser();
   190     
   190 
   191     CleanupStack::PushL( self );
   191     CleanupStack::PushL( self );
   192     self->ConstructL();
   192     self->ConstructL();
   193     CleanupStack::Pop();
   193     CleanupStack::Pop();
   194     
   194 
   195     return self;
   195     return self;
   196     }
   196     }
   197 
   197 
   198 // -----------------------------------------------------------------------------
   198 // -----------------------------------------------------------------------------
   199 // CDRMMessageParser::CDRMMessageParser
   199 // CDRMMessageParser::CDRMMessageParser
   217 //
   217 //
   218 EXPORT_C CDRMMessageParser::~CDRMMessageParser()
   218 EXPORT_C CDRMMessageParser::~CDRMMessageParser()
   219     {
   219     {
   220     TInt error = KErrNone;
   220     TInt error = KErrNone;
   221     TRAP( error, FinalizeMessageParserL() );
   221     TRAP( error, FinalizeMessageParserL() );
   222     
   222 
   223     Reset();
   223     Reset();
   224     
   224 
   225     User::Free( const_cast< TUint8* >( iInputBuffer.Ptr() ) );
   225     User::Free( const_cast< TUint8* >( iInputBuffer.Ptr() ) );
   226     }
   226     }
   227 
   227 
   228 // -----------------------------------------------------------------------------
   228 // -----------------------------------------------------------------------------
   229 // CDRMMessageParser::
   229 // CDRMMessageParser::
   230 // 
   230 //
   231 // -----------------------------------------------------------------------------
   231 // -----------------------------------------------------------------------------
   232 //
   232 //
   233 EXPORT_C void CDRMMessageParser::InitializeMessageParserL( RWriteStream& aStream )
   233 EXPORT_C void CDRMMessageParser::InitializeMessageParserL( RWriteStream& aStream )
   234     {
   234     {
   235     Reset();
   235     Reset();
   236     
   236 
   237     iDcfCreator = COma1DcfCreator::NewL();
   237     iDcfCreator = COma1DcfCreator::NewL();
   238     
   238 
   239     iOutputStream = aStream;
   239     iOutputStream = aStream;
   240     }
   240     }
   241 
   241 
   242 // -----------------------------------------------------------------------------
   242 // -----------------------------------------------------------------------------
   243 // CDRMMessageParser::ProcessDataL
   243 // CDRMMessageParser::ProcessDataL
   248     /*
   248     /*
   249     * What happens here is:
   249     * What happens here is:
   250     *   - a boundary string is located and extracted
   250     *   - a boundary string is located and extracted
   251     *   - MIME header is read, and based on content-type field the internal
   251     *   - MIME header is read, and based on content-type field the internal
   252     *     state is set to either EReadingRightsPart or EReadingContentPart.
   252     *     state is set to either EReadingRightsPart or EReadingContentPart.
   253     *   - after processing the MIME part, internal state is updated again to 
   253     *   - after processing the MIME part, internal state is updated again to
   254     *     EReadingHeaderPart if there are several MIME parts in the DRM 
   254     *     EReadingHeaderPart if there are several MIME parts in the DRM
   255     *     message.
   255     *     message.
   256     *   - data is consumed from iInputData in each phase.
   256     *   - data is consumed from iInputData in each phase.
   257     *   - after everything is done, internal state is set to EAllDone.
   257     *   - after everything is done, internal state is set to EAllDone.
   258     */
   258     */
   259     if ( iState & EBroken )
   259     if ( iState & EBroken )
   260         {
   260         {
   261         User::Leave( KErrNotReady );
   261         User::Leave( KErrNotReady );
   262         }
   262         }
   263     
   263 
   264     if ( iState & EAllDone )
   264     if ( iState & EAllDone )
   265         {
   265         {
   266         return;
   266         return;
   267         }
   267         }
   268     
   268 
   269     iInputData.Set( aMessageData );
   269     iInputData.Set( aMessageData );
   270     
   270 
   271     while( iInputData.Length() )
   271     while( iInputData.Length() )
   272         {
   272         {
   273         if ( iState & EReadingHeaderPart )
   273         if ( iState & EReadingHeaderPart )
   274             {
   274             {
   275             ReadHeaderL();
   275             ReadHeaderL();
   300 // Finalize the message parser.
   300 // Finalize the message parser.
   301 // -----------------------------------------------------------------------------
   301 // -----------------------------------------------------------------------------
   302 EXPORT_C void CDRMMessageParser::FinalizeMessageParserL()
   302 EXPORT_C void CDRMMessageParser::FinalizeMessageParserL()
   303     {
   303     {
   304     TInt error( KErrNone );
   304     TInt error( KErrNone );
   305     
   305 
   306     if ( iState & EEncryptStreamOk )
   306     if ( iState & EEncryptStreamOk )
   307         {
   307         {
   308         if ( iInputBuffer.Length() )
   308         if ( iInputBuffer.Length() )
   309             {
   309             {
   310             // Message is not parsed fully ==> error.
   310             // Message is not parsed fully ==> error.
   311             // Try to delete the RO if it is possible.
   311             // Try to delete the RO if it is possible.
   312             DeletePermission();
   312             DeletePermission();
   313             error = KDRMMessageMalformed;
   313             error = KDRMMessageMalformed;
   314             }
   314             }
   315             
   315 
   316         ClearBit( EEncryptStreamOk );
   316         ClearBit( EEncryptStreamOk );
   317         iDcfCreator->EncryptFinalizeL();
   317         iDcfCreator->EncryptFinalizeL();
   318         
   318 
   319         iOutputStream.CommitL();
   319         iOutputStream.CommitL();
   320         }
   320         }
   321 
   321 
   322     Reset();
   322     Reset();
   323     
   323 
   324     User::LeaveIfError( error );
   324     User::LeaveIfError( error );
   325     }
   325     }
   326 
   326 
   327 // -----------------------------------------------------------------------------
   327 // -----------------------------------------------------------------------------
   328 // CDRMMessageParser::ConstructL
   328 // CDRMMessageParser::ConstructL
   330 // -----------------------------------------------------------------------------
   330 // -----------------------------------------------------------------------------
   331 //
   331 //
   332 void CDRMMessageParser::ConstructL()
   332 void CDRMMessageParser::ConstructL()
   333     {
   333     {
   334     // Make some extra room for crazy b64decode().
   334     // Make some extra room for crazy b64decode().
   335     iInputBuffer.Set( reinterpret_cast< TUint8* >( 
   335     iInputBuffer.Set( reinterpret_cast< TUint8* >(
   336                         User::AllocL( KInputBufferSize + 2 ) ), 
   336                         User::AllocL( KInputBufferSize + 2 ) ),
   337                       0, 
   337                       0,
   338                       KInputBufferSize );
   338                       KInputBufferSize );
   339     }
   339     }
   340 
   340 
   341 // -----------------------------------------------------------------------------
   341 // -----------------------------------------------------------------------------
   342 // CDRMMessageParser::HandleContentDataL
   342 // CDRMMessageParser::HandleContentDataL
   349 void CDRMMessageParser::HandleContentDataL()
   349 void CDRMMessageParser::HandleContentDataL()
   350     {
   350     {
   351    TPtrC8 res( NULL, 0 );
   351    TPtrC8 res( NULL, 0 );
   352     TBool cont( ETrue );
   352     TBool cont( ETrue );
   353     TInt remainder( 0 );
   353     TInt remainder( 0 );
   354     
   354 
   355     // Loop until 
   355     // Loop until
   356     // - PrepareContentDataL leaves
   356     // - PrepareContentDataL leaves
   357     // - boundary end marker is found
   357     // - boundary end marker is found
   358     // - iInputBuffer is not updated anymore.
   358     // - iInputBuffer is not updated anymore.
   359     for ( PrepareContentDataL(); 
   359     for ( PrepareContentDataL();
   360           iInputBuffer.Length() && 
   360           iInputBuffer.Length() &&
   361               ( remainder != iInputBuffer.Length() ) && 
   361               ( remainder != iInputBuffer.Length() ) &&
   362               cont;
   362               cont;
   363           PrepareContentDataL() )
   363           PrepareContentDataL() )
   364         {
   364         {
   365         TInt pos = iInputBuffer.Find( *iBoundary );
   365         TInt pos = iInputBuffer.Find( *iBoundary );
   366         
   366 
   367         if ( pos >= 0 )
   367         if ( pos >= 0 )
   368             {
   368             {
   369             if ( pos < KBoundaryMarkLength + 1 ) 
   369             if ( pos < KBoundaryMarkLength + 1 )
   370                 {
   370                 {
   371                 SetBrokenStateL( KDRMMessageMalformed );
   371                 SetBrokenStateL( KDRMMessageMalformed );
   372                 }
   372                 }
   373             
   373 
   374             res.Set( iInputBuffer.Left( pos - KBoundaryMarkLength ) );
   374             res.Set( iInputBuffer.Left( pos - KBoundaryMarkLength ) );
   375             
   375 
   376             StripEndLineL( res );
   376             StripEndLineL( res );
   377             
   377 
   378             cont = EFalse;
   378             cont = EFalse;
   379             }
   379             }
   380         else
   380         else
   381             {
   381             {
   382             // All the data cannot be processed immediately, because
   382             // All the data cannot be processed immediately, because
   383             // there may be only a part of boundary string in this buffer
   383             // there may be only a part of boundary string in this buffer
   384             // and the rest is got from the next input descriptor.
   384             // and the rest is got from the next input descriptor.
   385             remainder = iBoundary->Length() + KBoundaryMarkLength + 1;
   385             remainder = iBoundary->Length() + KBoundaryMarkLength + 1;
   386             
   386 
   387             if ( iInputBuffer.Length() <= remainder )
   387             if ( iInputBuffer.Length() <= remainder )
   388                 {
   388                 {
   389                 return;
   389                 return;
   390                 }
   390                 }
   391             
   391 
   392             res.Set( iInputBuffer.Left( iInputBuffer.Length() - 
   392             res.Set( iInputBuffer.Left( iInputBuffer.Length() -
   393                                         remainder ) );
   393                                         remainder ) );
   394             }
   394             }
   395         
   395 
   396         if ( iState & EBase64 )
   396         if ( iState & EBase64 )
   397             {
   397             {
   398             iUsedFromInput = HandleBase64DataL( res );
   398             iUsedFromInput = HandleBase64DataL( res );
   399             }
   399             }
   400         
   400 
   401         else
   401         else
   402             {
   402             {
   403             iUsedFromInput = res.Length();
   403             iUsedFromInput = res.Length();
   404             }
   404             }
   405         
   405 
   406         ProcessContentDataL( res );
   406         ProcessContentDataL( res );
   407         
   407 
   408         CompressInputBuffer();
   408         CompressInputBuffer();
   409 
   409 
   410         remainder = iInputBuffer.Length(); 
   410         remainder = iInputBuffer.Length();
   411         }
   411         }
   412     
   412 
   413     if ( !cont )
   413     if ( !cont )
   414         {
   414         {
   415         // Discard all the remaining data.
   415         // Discard all the remaining data.
   416         ClearBit( EReadingContentPart );
   416         ClearBit( EReadingContentPart );
   417         SetBit( EAllDone );
   417         SetBit( EAllDone );
   429 // -----------------------------------------------------------------------------
   429 // -----------------------------------------------------------------------------
   430 //
   430 //
   431 void CDRMMessageParser::HandleRightsDataL()
   431 void CDRMMessageParser::HandleRightsDataL()
   432     {
   432     {
   433     TPtrC8 res( NULL, 0 );
   433     TPtrC8 res( NULL, 0 );
   434     
   434 
   435     do
   435     do
   436         {
   436         {
   437         res.Set( GetLineL() );
   437         res.Set( GetLineL() );
   438         
   438 
   439         TInt pos = res.Find( *iBoundary );
   439         TInt pos = res.Find( *iBoundary );
   440         
   440 
   441         if ( pos >= KBoundaryMarkLength )
   441         if ( pos >= KBoundaryMarkLength )
   442             {
   442             {
   443             if ( res.Left( KBoundaryMarkLength ) == KBoundaryMark )
   443             if ( res.Left( KBoundaryMarkLength ) == KBoundaryMark )
   444                 {
   444                 {
   445                 // Allow empty RO here. If it is not allowed by 
   445                 // Allow empty RO here. If it is not allowed by
   446                 // HandleRightsMessagePart(), an error is thrown.
   446                 // HandleRightsMessagePart(), an error is thrown.
   447                 TBool last = EFalse;
   447                 TBool last = EFalse;
   448                 
   448 
   449                 // Returns always true.
   449                 // Returns always true.
   450                 IsBoundary( res, last );
   450                 IsBoundary( res, last );
   451                 
   451 
   452                 if ( last )
   452                 if ( last )
   453                     {
   453                     {
   454                     TInt error( KErrNone );
   454                     TInt error( KErrNone );
   455                     RPointerArray< CDRMRights > rights;
   455                     RPointerArray< CDRMRights > rights;
   456                     TPtrC8 ptr( iInputBuffer.Ptr(),         
   456                     TPtrC8 ptr( iInputBuffer.Ptr(),
   457                                 pos - KBoundaryMarkLength );
   457                                 pos - KBoundaryMarkLength );
   458                     
   458 
   459                     error = ProcessRightsObject(ptr, rights);
   459                     error = ProcessRightsObject(ptr, rights);
   460                     rights.ResetAndDestroy();
   460                     rights.ResetAndDestroy();
   461                     
   461 
   462                     if ( !error )
   462                     if ( !error )
   463                         {
   463                         {
   464                         SetBit( EAllDone );
   464                         SetBit( EAllDone );
   465                         }
   465                         }
   466                     else
   466                     else
   468                         SetBrokenStateL( error );
   468                         SetBrokenStateL( error );
   469                         }
   469                         }
   470                     }
   470                     }
   471                 else
   471                 else
   472                     {
   472                     {
   473                     // Save the RO since the CID needs to be either changed 
   473                     // Save the RO since the CID needs to be either changed
   474                     // or created.
   474                     // or created.
   475                     iRightsData = iInputBuffer.Left( iUsedFromInput - 
   475                     iRightsData = iInputBuffer.Left( iUsedFromInput -
   476                                                      res.Length() ).AllocL();
   476                                                      res.Length() ).AllocL();
   477                     }
   477                     }
   478                 
   478 
   479                 CompressInputBuffer();
   479                 CompressInputBuffer();
   480                 
   480 
   481                 ClearBit( EReadingRightsPart );
   481                 ClearBit( EReadingRightsPart );
   482                 ClearBit( EGotContentType );
   482                 ClearBit( EGotContentType );
   483                 ClearBit( EGotContentEncoding );
   483                 ClearBit( EGotContentEncoding );
   484 
   484 
   485                 SetBit( EGotRightsPart );
   485                 SetBit( EGotRightsPart );
   486                 SetBit( EReadingHeaderPart );
   486                 SetBit( EReadingHeaderPart );
   487                 
   487 
   488                 res.Set( NULL, 0 );
   488                 res.Set( NULL, 0 );
   489 #ifndef __DRM_FULL
   489 #ifndef __DRM_FULL
   490                 User::Leave(KErrNotSupported);
   490                 User::Leave(KErrNotSupported);
   491 #endif                
   491 #endif
   492                 }
   492                 }
   493             else
   493             else
   494                 {
   494                 {
   495                 SetBrokenStateL( KDRMMessageMalformed );
   495                 SetBrokenStateL( KDRMMessageMalformed );
   496                 }
   496                 }
   512 // -----------------------------------------------------------------------------
   512 // -----------------------------------------------------------------------------
   513 //
   513 //
   514 void CDRMMessageParser::FindBoundaryL()
   514 void CDRMMessageParser::FindBoundaryL()
   515     {
   515     {
   516     TPtrC8 line( NULL, 0 );
   516     TPtrC8 line( NULL, 0 );
   517     
   517 
   518     FOREVER
   518     FOREVER
   519         {
   519         {
   520         line.Set( GetLineL() );
   520         line.Set( GetLineL() );
   521         
   521 
   522         if ( line.Length() > KBoundaryMarkLength )
   522         if ( line.Length() > KBoundaryMarkLength )
   523             {
   523             {
   524             TInt size = 0;
   524             TInt size = 0;
   525             
   525 
   526             if ( line.Left( KBoundaryMarkLength ) == KBoundaryMark )
   526             if ( line.Left( KBoundaryMarkLength ) == KBoundaryMark )
   527                 {
   527                 {
   528                 size = line.Length() - KBoundaryMarkLength - 1;
   528                 size = line.Length() - KBoundaryMarkLength - 1;
   529                 
   529 
   530                 if ( line[ line.Length() - 2 ] == '\r' )
   530                 if ( line[ line.Length() - 2 ] == '\r' )
   531                     {
   531                     {
   532                     --size;
   532                     --size;
   533                     }
   533                     }
   534                 
   534 
   535                 iBoundary = line.Mid( KBoundaryMarkLength, size ).AllocL();
   535                 iBoundary = line.Mid( KBoundaryMarkLength, size ).AllocL();
   536                 
   536 
   537                 SetBit( EGotBoundary );
   537                 SetBit( EGotBoundary );
   538                 SetBit( EReadingHeaderPart );
   538                 SetBit( EReadingHeaderPart );
   539                 
   539 
   540                 CompressInputBuffer();
   540                 CompressInputBuffer();
   541                 
   541 
   542                 return;
   542                 return;
   543                 }
   543                 }
   544             }
   544             }
   545         else
   545         else
   546             {
   546             {
   547             if ( line.Length() == 0 )
   547             if ( line.Length() == 0 )
   548                 {
   548                 {
   549                 return;
   549                 return;
   550                 }
   550                 }
   551             }
   551             }
   552         
   552 
   553         // Something else, not interested.
   553         // Something else, not interested.
   554         CompressInputBuffer();
   554         CompressInputBuffer();
   555         }
   555         }
   556     }
   556     }
   557 
   557 
   558 // ----------------------------------------------------------------------------
   558 // ----------------------------------------------------------------------------
   559 // CDRMMessageParser::ReadHeaderL
   559 // CDRMMessageParser::ReadHeaderL
   560 // The boundary is read and the following part is (should be) either a RO part
   560 // The boundary is read and the following part is (should be) either a RO part
   561 // or content part. The data is kept in iInputBuffer until the whole header 
   561 // or content part. The data is kept in iInputBuffer until the whole header
   562 // part of the MIME header part is received. After plain "\r\n" line is 
   562 // part of the MIME header part is received. After plain "\r\n" line is
   563 // received and content-type is defined, iState is updated.
   563 // received and content-type is defined, iState is updated.
   564 // ----------------------------------------------------------------------------
   564 // ----------------------------------------------------------------------------
   565 //
   565 //
   566 void CDRMMessageParser::ReadHeaderL()
   566 void CDRMMessageParser::ReadHeaderL()
   567     {
   567     {
   568     TPtrC8 line( NULL, 0 );
   568     TPtrC8 line( NULL, 0 );
   569     TPtrC8 ptr( NULL, 0 );
   569     TPtrC8 ptr( NULL, 0 );
   570     
   570 
   571     FOREVER
   571     FOREVER
   572         {
   572         {
   573         ///////////////////////////////////////////////////////////////////
   573         ///////////////////////////////////////////////////////////////////
   574         // Process the MIME header line-by-line. Process the lines if they
   574         // Process the MIME header line-by-line. Process the lines if they
   575         // contain some information that is found useful. Update the 
   575         // contain some information that is found useful. Update the
   576         // internal state according to findings.
   576         // internal state according to findings.
   577         ///////////////////////////////////////////////////////////////////
   577         ///////////////////////////////////////////////////////////////////
   578         line.Set( GetLineL() );
   578         line.Set( GetLineL() );
   579         
   579 
   580         if ( line.Length() )
   580         if ( line.Length() )
   581             {
   581             {
   582             if ( line == KEndLine || line == KNewLine )
   582             if ( line == KEndLine || line == KNewLine )
   583                 {
   583                 {
   584                 ///////////////////////////////////////////////
   584                 ///////////////////////////////////////////////
   585                 // MIME header is read. Check what to do next.
   585                 // MIME header is read. Check what to do next.
   586                 ///////////////////////////////////////////////
   586                 ///////////////////////////////////////////////
   587                 if ( iState & EGotContentType )
   587                 if ( iState & EGotContentType )
   588                     {
   588                     {
   589                     // Sanity check: Either EReadingRightsPart or 
   589                     // Sanity check: Either EReadingRightsPart or
   590                     // EReadingContentPart must defined.
   590                     // EReadingContentPart must defined.
   591                     __ASSERT_DEBUG( ( iState & EReadingRightsPart ) ||
   591                     __ASSERT_DEBUG( ( iState & EReadingRightsPart ) ||
   592                         ( iState & EReadingContentPart ), 
   592                         ( iState & EReadingContentPart ),
   593                         User::Invariant() );
   593                         User::Invariant() );
   594                     
   594 
   595                     ClearBit( EReadingHeaderPart );
   595                     ClearBit( EReadingHeaderPart );
   596                     
   596 
   597                     CompressInputBuffer();
   597                     CompressInputBuffer();
   598                     
   598 
   599                     // Check which part was read.
   599                     // Check which part was read.
   600                     // If content part is being processed, some checkings 
   600                     // If content part is being processed, some checkings
   601                     // need to be made.
   601                     // need to be made.
   602                     if ( iState & EReadingContentPart )
   602                     if ( iState & EReadingContentPart )
   603                         {
   603                         {
   604                         if ( iContentType->CompareF( KDRMContentType ) == 0 )
   604                         if ( iContentType->CompareF( KDRMContentType ) == 0 )
   605                             {
   605                             {
   606                             if ( iState & EGotRightsPart )
   606                             if ( iState & EGotRightsPart )
   607                                 {
   607                                 {
   608                                 // CD DCF.
   608                                 // CD DCF.
   609                                 SetBrokenStateL( KErrCANotSupported );
   609                                 SetBrokenStateL( KErrCANotSupported );
   610                                 }
   610                                 }
   611                             
   611 
   612                             InitDCFBufferL();
   612                             InitDCFBufferL();
   613 
   613 
   614                             SetBit( EDCFFile );
   614                             SetBit( EDCFFile );
   615                             }
   615                             }
   616                         else
   616                         else
   617                             {
   617                             {
   618                             // Non-DCF FL content or normal CD content. 
   618                             // Non-DCF FL content or normal CD content.
   619                             // Create or modify the CID, save the RO.
   619                             // Create or modify the CID, save the RO.
   620                             HandleFlContentL();
   620                             HandleFlContentL();
   621                             
   621 
   622                              iDcfCreator->EncryptInitializeL(
   622                              iDcfCreator->EncryptInitializeL(
   623                                 iOutputStream,
   623                                 iOutputStream,
   624                                 *iContentType,
   624                                 *iContentType,
   625                                 iRightsObject );
   625                                 iRightsObject );
   626                             SetBit( EEncryptStreamOk );
   626                             SetBit( EEncryptStreamOk );
   627                             
   627 
   628                             // The RO handle iRightsObject is kept in order 
   628                             // The RO handle iRightsObject is kept in order
   629                             // to delete the rights in case of content 
   629                             // to delete the rights in case of content
   630                             // encryption error. In that case, this will 
   630                             // encryption error. In that case, this will
   631                             // generate unnecessary "RO Added / RO Deleted"
   631                             // generate unnecessary "RO Added / RO Deleted"
   632                             // notifications, but so what. "More correct"
   632                             // notifications, but so what. "More correct"
   633                             // way of doing would be modifying 
   633                             // way of doing would be modifying
   634                             // EncryptInitialize not to 
   634                             // EncryptInitialize not to
   635                             // save the RO, but then the key would have to
   635                             // save the RO, but then the key would have to
   636                             // be given to it by other means. Since we are
   636                             // be given to it by other means. Since we are
   637                             // not their "friend" class, we cannot access 
   637                             // not their "friend" class, we cannot access
   638                             // their members, and making them to ask our
   638                             // their members, and making them to ask our
   639                             // members when doing EncryptInitialize/Finalize
   639                             // members when doing EncryptInitialize/Finalize
   640                             // might cause some problems perhaps.
   640                             // might cause some problems perhaps.
   641                             }
   641                             }
   642                         
   642 
   643                         delete iContentType;
   643                         delete iContentType;
   644                         iContentType = NULL;
   644                         iContentType = NULL;
   645                         }
   645                         }
   646                     
   646 
   647                     return;
   647                     return;
   648                     }
   648                     }
   649                 
   649 
   650                 // Empty MIME header.
   650                 // Empty MIME header.
   651                 SetBrokenStateL( KDRMMessageMalformed );
   651                 SetBrokenStateL( KDRMMessageMalformed );
   652                 }
   652                 }
   653             
   653 
   654             ///////////////////////////////////
   654             ///////////////////////////////////
   655             // Check the line for content-type.
   655             // Check the line for content-type.
   656             ///////////////////////////////////
   656             ///////////////////////////////////
   657             if ( line.Length() > KContentType().Length()  &&  
   657             if ( line.Length() > KContentType().Length()  &&
   658                 !( line.Left( KContentType().Length() ).CompareF( KContentType ) ) )
   658                 !( line.Left( KContentType().Length() ).CompareF( KContentType ) ) )
   659                 {
   659                 {
   660                 if ( iState & EGotContentType )
   660                 if ( iState & EGotContentType )
   661                     {
   661                     {
   662                     // Content-type given twice.
   662                     // Content-type given twice.
   663                     SetBrokenStateL( KDRMMessageMalformed );
   663                     SetBrokenStateL( KDRMMessageMalformed );
   664                     }
   664                     }
   665                 
   665 
   666                 ptr.Set( HeaderValueL( line ) );
   666                 ptr.Set( HeaderValueL( line ) );
   667                 
   667 
   668                 SetBit( EGotContentType );
   668                 SetBit( EGotContentType );
   669                 
   669 
   670                 // Which part this is: rights or the actual content?
   670                 // Which part this is: rights or the actual content?
   671                 if ( ( ptr.CompareF( KDRMXMLRightsType ) == 0 ) ||
   671                 if ( ( ptr.CompareF( KDRMXMLRightsType ) == 0 ) ||
   672                     ( ptr.CompareF( KDRMWBXMLRightsType ) == 0 ) )
   672                     ( ptr.CompareF( KDRMWBXMLRightsType ) == 0 ) )
   673                     {
   673                     {
   674                     if ( iState & EGotRightsPart )
   674                     if ( iState & EGotRightsPart )
   675                         {
   675                         {
   676                         // Rights are given twice.
   676                         // Rights are given twice.
   677                         SetBrokenStateL( KDRMMessageMalformed );
   677                         SetBrokenStateL( KDRMMessageMalformed );
   678                         }
   678                         }
   679                     
   679 
   680                     SetBit( EReadingRightsPart );
   680                     SetBit( EReadingRightsPart );
   681                     }
   681                     }
   682                 else
   682                 else
   683                     {
   683                     {
   684                     if ( iState & EGotContentPart )
   684                     if ( iState & EGotContentPart )
   685                         {
   685                         {
   686                         SetBrokenStateL( KDRMMessageMalformed );
   686                         SetBrokenStateL( KDRMMessageMalformed );
   687                         }
   687                         }
   688                     
   688 
   689                     SetBit( EReadingContentPart );
   689                     SetBit( EReadingContentPart );
   690                     
   690 
   691                     // Content-type is saved for future use.
   691                     // Content-type is saved for future use.
   692                     iContentType = ptr.AllocL();
   692                     iContentType = ptr.AllocL();
   693                     }
   693                     }
   694                 }
   694                 }
   695             else
   695             else
   704                     if ( iState & EGotContentEncoding )
   704                     if ( iState & EGotContentEncoding )
   705                         {
   705                         {
   706                         // Double line.
   706                         // Double line.
   707                         SetBrokenStateL( KDRMMessageMalformed );
   707                         SetBrokenStateL( KDRMMessageMalformed );
   708                         }
   708                         }
   709                     
   709 
   710                     ptr.Set( HeaderValueL( line ) );
   710                     ptr.Set( HeaderValueL( line ) );
   711                     
   711 
   712                     SetBit( EGotContentEncoding );
   712                     SetBit( EGotContentEncoding );
   713 
   713 
   714                     // Throw an error if content-transfer-encoding 
   714                     // Throw an error if content-transfer-encoding
   715                     // is something we don't support.
   715                     // is something we don't support.
   716                     if ( ptr.CompareF( KEncoding8bit ) &&
   716                     if ( ptr.CompareF( KEncoding8bit ) &&
   717                         ptr.CompareF( KEncoding7bit) &&
   717                         ptr.CompareF( KEncoding7bit) &&
   718                         ptr.CompareF( KEncodingBinary ) )
   718                         ptr.CompareF( KEncodingBinary ) )
   719                         {
   719                         {
   720                         if ( ptr.CompareF( KEncodingBase64 ) )
   720                         if ( ptr.CompareF( KEncodingBase64 ) )
   721                             {
   721                             {
   722                             SetBrokenStateL( KErrCANotSupported );
   722                             SetBrokenStateL( KErrCANotSupported );
   723                             }
   723                             }
   724                         
   724 
   725                         // So it has to be Base64.
   725                         // So it has to be Base64.
   726                         SetBit( EBase64 );
   726                         SetBit( EBase64 );
   727                         }
   727                         }
   728                     }
   728                     }
   729                 else
   729                 else
   730                     {
   730                     {
   731                     //////////////////////////////////////////
   731                     //////////////////////////////////////////
   732                     // Check the line for end boundary marker.
   732                     // Check the line for end boundary marker.
   733                     //////////////////////////////////////////
   733                     //////////////////////////////////////////
   734                     TBool final( EFalse );
   734                     TBool final( EFalse );
   735                     
   735 
   736                     if ( IsBoundary( line, final ) )
   736                     if ( IsBoundary( line, final ) )
   737                         {
   737                         {
   738                         SetBrokenStateL( KDRMMessageMalformed );
   738                         SetBrokenStateL( KDRMMessageMalformed );
   739                         }
   739                         }
   740                     
   740 
   741                     // Else: some X-field, parameter or something else. 
   741                     // Else: some X-field, parameter or something else.
   742                     // The line is ignored.
   742                     // The line is ignored.
   743                     }
   743                     }
   744                 }
   744                 }
   745             
   745 
   746             CompressInputBuffer();
   746             CompressInputBuffer();
   747             }
   747             }
   748             
   748 
   749         else
   749         else
   750             {
   750             {
   751             // No line available yet.
   751             // No line available yet.
   752             return;
   752             return;
   753             }
   753             }
   761 //
   761 //
   762 TPtrC8 CDRMMessageParser::GetLineL()
   762 TPtrC8 CDRMMessageParser::GetLineL()
   763     {
   763     {
   764     TInt pos = 0;
   764     TInt pos = 0;
   765     TPtrC8 res( NULL, 0 );
   765     TPtrC8 res( NULL, 0 );
   766     
   766 
   767     if ( iInputBuffer.Length() > iUsedFromInput )
   767     if ( iInputBuffer.Length() > iUsedFromInput )
   768         {
   768         {
   769         pos = iInputBuffer.Mid( iUsedFromInput ).Find( KNewLine );
   769         pos = iInputBuffer.Mid( iUsedFromInput ).Find( KNewLine );
   770         
   770 
   771         if ( pos >= 0 )
   771         if ( pos >= 0 )
   772             {
   772             {
   773             res.Set( iInputBuffer.Mid( iUsedFromInput, pos - iUsedFromInput + 1 ) );
   773             res.Set( iInputBuffer.Mid( iUsedFromInput, pos - iUsedFromInput + 1 ) );
   774             iUsedFromInput = pos + 1;
   774             iUsedFromInput = pos + 1;
   775             }
   775             }
   776         }
   776         }
   777     
   777 
   778     if ( res.Length() == 0 )
   778     if ( res.Length() == 0 )
   779         {
   779         {
   780         if ( iInputData.Length() )
   780         if ( iInputData.Length() )
   781             {
   781             {
   782             pos = iInputData.Find( KNewLine );
   782             pos = iInputData.Find( KNewLine );
   783             
   783 
   784             if ( pos < 0 )
   784             if ( pos < 0 )
   785                 {
   785                 {
   786                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() < 
   786                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() <
   787                     iInputData.Length() )
   787                     iInputData.Length() )
   788                     {
   788                     {
   789                     SetBrokenStateL( KDRMMessageMalformed );
   789                     SetBrokenStateL( KDRMMessageMalformed );
   790                     }
   790                     }
   791                 
   791 
   792                 iInputBuffer.Append( iInputData );
   792                 iInputBuffer.Append( iInputData );
   793                 iInputData.Set( NULL, 0 );
   793                 iInputData.Set( NULL, 0 );
   794                 }
   794                 }
   795             else
   795             else
   796                 {
   796                 {
   797                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() <
   797                 if ( iInputBuffer.MaxSize() - iInputBuffer.Length() <
   798                     pos + 1 )
   798                     pos + 1 )
   799                     {
   799                     {
   800                     SetBrokenStateL( KDRMMessageMalformed );
   800                     SetBrokenStateL( KDRMMessageMalformed );
   801                     }
   801                     }
   802                 
   802 
   803                 iInputBuffer.Append( iInputData.Left( pos + 1 ) );
   803                 iInputBuffer.Append( iInputData.Left( pos + 1 ) );
   804                 res.Set( iInputBuffer.Mid( iUsedFromInput ) );
   804                 res.Set( iInputBuffer.Mid( iUsedFromInput ) );
   805                 iUsedFromInput = iInputBuffer.Length();
   805                 iUsedFromInput = iInputBuffer.Length();
   806                 
   806 
   807                 iInputData.Set( iInputData.Mid( pos + 1 ) );
   807                 iInputData.Set( iInputData.Mid( pos + 1 ) );
   808                 }
   808                 }
   809             }
   809             }
   810         }
   810         }
   811     
   811 
   812     return res;
   812     return res;
   813     }
   813     }
   814 
   814 
   815 // -----------------------------------------------------------------------------
   815 // -----------------------------------------------------------------------------
   816 // CDRMMessageParser::HeaderValueL
   816 // CDRMMessageParser::HeaderValueL
   819 //
   819 //
   820 TPtrC8 CDRMMessageParser::HeaderValueL( const TDesC8& aLine )
   820 TPtrC8 CDRMMessageParser::HeaderValueL( const TDesC8& aLine )
   821     {
   821     {
   822     TInt pos( 0 );
   822     TInt pos( 0 );
   823     TPtrC8 res( NULL, 0 );
   823     TPtrC8 res( NULL, 0 );
   824     
   824 
   825     pos = aLine.Find( KColon );
   825     pos = aLine.Find( KColon );
   826     
   826 
   827     if ( pos <= 0 )
   827     if ( pos <= 0 )
   828         {
   828         {
   829         SetBrokenStateL( KDRMMessageMalformed );
   829         SetBrokenStateL( KDRMMessageMalformed );
   830         }
   830         }
   831     
   831 
   832     pos += 1;
   832     pos += 1;
   833     
   833 
   834     while ( pos < aLine.Length() && 
   834     while ( pos < aLine.Length() &&
   835             TChar( aLine[ pos ] ).IsSpace() )
   835             TChar( aLine[ pos ] ).IsSpace() )
   836         {
   836         {
   837         ++pos;
   837         ++pos;
   838         }
   838         }
   839 
   839 
   840     // Don't overindex.   
   840     // Don't overindex.
   841     if ( pos == aLine.Length() )
   841     if ( pos == aLine.Length() )
   842         {
   842         {
   843         // Full of whitespaces.
   843         // Full of whitespaces.
   844         SetBrokenStateL( KDRMMessageMalformed );
   844         SetBrokenStateL( KDRMMessageMalformed );
   845         }
   845         }
   846 
   846 
   847     // Drop possible parameters.
   847     // Drop possible parameters.
   848     res.Set( aLine.Mid( pos ) );
   848     res.Set( aLine.Mid( pos ) );
   849     pos = res.Find( KSemiColon );
   849     pos = res.Find( KSemiColon );
   850     
   850 
   851     if ( pos >= 0 )
   851     if ( pos >= 0 )
   852         {
   852         {
   853         res.Set( res.Left( pos ) );
   853         res.Set( res.Left( pos ) );
   854         }
   854         }
   855     
   855 
   856     pos = res.Length();
   856     pos = res.Length();
   857     
   857 
   858     if ( !pos )
   858     if ( !pos )
   859         {
   859         {
   860         // Just parameters, no actual value.
   860         // Just parameters, no actual value.
   861         SetBrokenStateL( KDRMMessageMalformed );
   861         SetBrokenStateL( KDRMMessageMalformed );
   862         }
   862         }
   863 
   863 
   864     // This can't underflow, since otherwise there would be only 
   864     // This can't underflow, since otherwise there would be only
   865     // semicolon & parameters (checked earlier).
   865     // semicolon & parameters (checked earlier).
   866     while( TChar( res[ pos - 1 ] ).IsSpace() )
   866     while( TChar( res[ pos - 1 ] ).IsSpace() )
   867         {
   867         {
   868         --pos;
   868         --pos;
   869         }
   869         }
   870     
   870 
   871     return res.Left( pos );
   871     return res.Left( pos );
   872     }
   872     }
   873 
   873 
   874 // -----------------------------------------------------------------------------
   874 // -----------------------------------------------------------------------------
   875 // CDRMMessageParser::CompressInputBuffer
   875 // CDRMMessageParser::CompressInputBuffer
   879 void CDRMMessageParser::CompressInputBuffer()
   879 void CDRMMessageParser::CompressInputBuffer()
   880     {
   880     {
   881     if ( iUsedFromInput )
   881     if ( iUsedFromInput )
   882         {
   882         {
   883         const TInt size = iInputBuffer.Length() - iUsedFromInput;
   883         const TInt size = iInputBuffer.Length() - iUsedFromInput;
   884         
   884 
   885         Mem::Copy( const_cast< TUint8* >( iInputBuffer.Ptr() ),
   885         Mem::Copy( const_cast< TUint8* >( iInputBuffer.Ptr() ),
   886             iInputBuffer.Ptr() + iUsedFromInput,
   886             iInputBuffer.Ptr() + iUsedFromInput,
   887             size );
   887             size );
   888         
   888 
   889         iInputBuffer.SetLength( size );
   889         iInputBuffer.SetLength( size );
   890         iUsedFromInput = 0;
   890         iUsedFromInput = 0;
   891         }
   891         }
   892     }
   892     }
   893 
   893 
   902         {
   902         {
   903         if ( iInputBuffer.Length() == iInputBuffer.MaxSize() )
   903         if ( iInputBuffer.Length() == iInputBuffer.MaxSize() )
   904             {
   904             {
   905             SetBrokenStateL( KDRMMessageMalformed );
   905             SetBrokenStateL( KDRMMessageMalformed );
   906             }
   906             }
   907         
   907 
   908         const TInt size = Min( iInputBuffer.MaxSize() - iInputBuffer.Length(), 
   908         const TInt size = Min( iInputBuffer.MaxSize() - iInputBuffer.Length(),
   909                                iInputData.Length() );
   909                                iInputData.Length() );
   910         
   910 
   911         iInputBuffer.Append( iInputData.Left( size ) );
   911         iInputBuffer.Append( iInputData.Left( size ) );
   912         
   912 
   913         iInputData.Set( iInputData.Mid( size ) );
   913         iInputData.Set( iInputData.Mid( size ) );
   914         }
   914         }
   915     }
   915     }
   916     
   916 
   917 // -----------------------------------------------------------------------------
   917 // -----------------------------------------------------------------------------
   918 // CDRMMessageParser::HandleBase64DataL
   918 // CDRMMessageParser::HandleBase64DataL
   919 // Decode base64 encoded data from and to aData descriptor.
   919 // Decode base64 encoded data from and to aData descriptor.
   920 // 
   920 //
   921 // -----------------------------------------------------------------------------
   921 // -----------------------------------------------------------------------------
   922 //
   922 //
   923 TInt CDRMMessageParser::HandleBase64DataL( TPtrC8& aData )
   923 TInt CDRMMessageParser::HandleBase64DataL( TPtrC8& aData )
   924     {
   924     {
   925     TUint8* consumed = const_cast< TUint8* >( aData.Ptr() );
   925     TUint8* consumed = const_cast< TUint8* >( aData.Ptr() );
   936                 consumed = const_cast< TUint8* >( aData.Ptr() ) + temp1;
   936                 consumed = const_cast< TUint8* >( aData.Ptr() ) + temp1;
   937                 temp2 = 0;
   937                 temp2 = 0;
   938                 }
   938                 }
   939             }
   939             }
   940         }
   940         }
   941     
   941 
   942     if ( consumed != aData.Ptr() )
   942     if ( consumed != aData.Ptr() )
   943         {
   943         {
   944         User::LeaveIfError( b64decode( const_cast< TUint8* >( aData.Ptr() ), 
   944         User::LeaveIfError( b64decode( const_cast< TUint8* >( aData.Ptr() ),
   945                                        consumed - aData.Ptr() + 1,
   945                                        consumed - aData.Ptr() + 1,
   946                                        const_cast< TUint8* >( aData.Ptr() ), 
   946                                        const_cast< TUint8* >( aData.Ptr() ),
   947                                        &temp1 ) );
   947                                        &temp1 ) );
   948         
   948 
   949         aData.Set( aData.Ptr(), temp1 );
   949         aData.Set( aData.Ptr(), temp1 );
   950 
   950 
   951         temp1 = consumed - aData.Ptr() + 1;
   951         temp1 = consumed - aData.Ptr() + 1;
   952         }
   952         }
   953         
   953 
   954     else
   954     else
   955         {
   955         {
   956         aData.Set( aData.Ptr(), 0 );
   956         aData.Set( aData.Ptr(), 0 );
   957         temp1 = 0;
   957         temp1 = 0;
   958         }
   958         }
   968 // -----------------------------------------------------------------------------
   968 // -----------------------------------------------------------------------------
   969 //
   969 //
   970 void CDRMMessageParser::StripEndLineL( TPtrC8& aBuf )
   970 void CDRMMessageParser::StripEndLineL( TPtrC8& aBuf )
   971     {
   971     {
   972     TInt newSize( aBuf.Length() );
   972     TInt newSize( aBuf.Length() );
   973     
   973 
   974     if ( aBuf.Right( 1 ) == KNewLine )
   974     if ( aBuf.Right( 1 ) == KNewLine )
   975         {
   975         {
   976         --newSize;
   976         --newSize;
   977         
   977 
   978         if ( ( aBuf.Length() > 1 ) && 
   978         if ( ( aBuf.Length() > 1 ) &&
   979             ( aBuf.Right( 2 ) == KEndLine ) )
   979             ( aBuf.Right( 2 ) == KEndLine ) )
   980             {
   980             {
   981             --newSize;
   981             --newSize;
   982             }
   982             }
   983         
   983 
   984         aBuf.Set( aBuf.Left( newSize ) );
   984         aBuf.Set( aBuf.Left( newSize ) );
   985         }
   985         }
   986     else
   986     else
   987         {
   987         {
   988         SetBrokenStateL( KDRMMessageMalformed );
   988         SetBrokenStateL( KDRMMessageMalformed );
   993 // CDRMMessageParser::IsBoundary
   993 // CDRMMessageParser::IsBoundary
   994 // Check if the given line is a boundary line. Also check if the line is
   994 // Check if the given line is a boundary line. Also check if the line is
   995 // the end boundary.
   995 // the end boundary.
   996 // -----------------------------------------------------------------------------
   996 // -----------------------------------------------------------------------------
   997 //
   997 //
   998 TBool CDRMMessageParser::IsBoundary( const TDesC8& aLine, TBool& aLast ) const 
   998 TBool CDRMMessageParser::IsBoundary( const TDesC8& aLine, TBool& aLast ) const
   999     {
   999     {
  1000     TBool res = EFalse;
  1000     TBool res = EFalse;
  1001     
  1001 
  1002     __ASSERT_DEBUG( iBoundary, User::Invariant() );
  1002     __ASSERT_DEBUG( iBoundary, User::Invariant() );
  1003     
  1003 
  1004     if ( iState & EGotBoundary )
  1004     if ( iState & EGotBoundary )
  1005         {
  1005         {
  1006         if ( aLine.Length() > KBoundaryMarkLength + iBoundary->Length() )
  1006         if ( aLine.Length() > KBoundaryMarkLength + iBoundary->Length() )
  1007             {
  1007             {
  1008             TPtrC8 tmp( NULL, 0 );
  1008             TPtrC8 tmp( NULL, 0 );
  1009             
  1009 
  1010             if ( ( aLine.Left( KBoundaryMarkLength ) == KBoundaryMark ) &&
  1010             if ( ( aLine.Left( KBoundaryMarkLength ) == KBoundaryMark ) &&
  1011                 ( aLine.Mid( KBoundaryMarkLength, iBoundary->Length() ).
  1011                 ( aLine.Mid( KBoundaryMarkLength, iBoundary->Length() ).
  1012                 Compare( *iBoundary ) == 0 ) )
  1012                 Compare( *iBoundary ) == 0 ) )
  1013                 {
  1013                 {
  1014                 res = ETrue;
  1014                 res = ETrue;
  1015                 
  1015 
  1016                 tmp.Set( aLine.Right( aLine.Length() - 
  1016                 tmp.Set( aLine.Right( aLine.Length() -
  1017                     KBoundaryMarkLength - 
  1017                     KBoundaryMarkLength -
  1018                     iBoundary->Length() ) );
  1018                     iBoundary->Length() ) );
  1019                 
  1019 
  1020                 if ( ( tmp.Length() >= KBoundaryMarkLength ) &&
  1020                 if ( ( tmp.Length() >= KBoundaryMarkLength ) &&
  1021                     ( tmp.Left( KBoundaryMarkLength ) == KBoundaryMark ) )
  1021                     ( tmp.Left( KBoundaryMarkLength ) == KBoundaryMark ) )
  1022                     {
  1022                     {
  1023                     aLast = ETrue;
  1023                     aLast = ETrue;
  1024                     }
  1024                     }
  1025                 }
  1025                 }
  1026             }
  1026             }
  1027         }
  1027         }
  1028     
  1028 
  1029     return res;
  1029     return res;
  1030     }
  1030     }
  1031 
  1031 
  1032 // -----------------------------------------------------------------------------
  1032 // -----------------------------------------------------------------------------
  1033 // CDRMMessageParser::HandleFlContentL
  1033 // CDRMMessageParser::HandleFlContentL
  1035 // -----------------------------------------------------------------------------
  1035 // -----------------------------------------------------------------------------
  1036 //
  1036 //
  1037 void CDRMMessageParser::HandleFlContentL()
  1037 void CDRMMessageParser::HandleFlContentL()
  1038     {
  1038     {
  1039     __ASSERT_DEBUG( !( iState & EDCFFile ), User::Invariant() );
  1039     __ASSERT_DEBUG( !( iState & EDCFFile ), User::Invariant() );
  1040     
  1040 
  1041     if ( iRightsData )
  1041     if ( iRightsData )
  1042         {
  1042         {
  1043         HBufC8* cid( NULL );
  1043         HBufC8* cid( NULL );
  1044         HBufC8* buf( NULL );
  1044         HBufC8* buf( NULL );
  1045         
  1045 
  1046         // RO was found from DRM message.
  1046         // RO was found from DRM message.
  1047         CreateCDCIDL( cid );
  1047         CreateCDCIDL( cid );
  1048         CleanupStack::PushL( cid );
  1048         CleanupStack::PushL( cid );
  1049       
  1049 
  1050         buf = iRightsData;
  1050         buf = iRightsData;
  1051         CleanupStack::PushL( buf );
  1051         CleanupStack::PushL( buf );
  1052         iRightsData = NULL;
  1052         iRightsData = NULL;
  1053         
  1053 
  1054         ProcessRightsDataL( *cid, 
  1054         ProcessRightsDataL( *cid,
  1055                             *buf );
  1055                             *buf );
  1056         
  1056 
  1057         CleanupStack::PopAndDestroy(); // buf
  1057         CleanupStack::PopAndDestroy(); // buf
  1058         CleanupStack::PopAndDestroy(); // cid
  1058         CleanupStack::PopAndDestroy(); // cid
  1059         }
  1059         }
  1060     else
  1060     else
  1061         {
  1061         {
  1067         }
  1067         }
  1068     }
  1068     }
  1069 
  1069 
  1070 // -----------------------------------------------------------------------------
  1070 // -----------------------------------------------------------------------------
  1071 // CDRMMessageParser::ProcessRightsData
  1071 // CDRMMessageParser::ProcessRightsData
  1072 // Process DRM message -style rights object and fetch it to iRightsObject if 
  1072 // Process DRM message -style rights object and fetch it to iRightsObject if
  1073 // necessary.
  1073 // necessary.
  1074 // -----------------------------------------------------------------------------
  1074 // -----------------------------------------------------------------------------
  1075 //
  1075 //
  1076 void CDRMMessageParser::ProcessRightsDataL( 
  1076 void CDRMMessageParser::ProcessRightsDataL(
  1077                             const TDesC8& aCID,
  1077                             const TDesC8& aCID,
  1078                             const TDesC8& aData )
  1078                             const TDesC8& aData )
  1079     {
  1079     {
  1080     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
  1080     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
  1081     
  1081 
  1082     TInt start = aData.Find(KRightsStartTag);
  1082     TInt start = aData.Find(KRightsStartTag);
  1083     TInt end = aData.LocateReverse('>');
  1083     TInt end = aData.LocateReverse('>');
  1084     
  1084 
  1085     if ( start >= 0 && end > start )
  1085     if ( start >= 0 && end > start )
  1086         {
  1086         {
  1087         TDRMUniqueID localID( 0 );
  1087         TDRMUniqueID localID( 0 );
  1088         CDrmRightsParser* parser( NULL );
  1088         CDrmRightsParser* parser( NULL );
  1089         CDRMAsset* asset( NULL );
  1089         CDRMAsset* asset( NULL );
  1090         RDRMRightsClient client;
  1090         RDRMRightsClient client;
  1091         TPtrC8 ptr( &aData[start], end - start + 1 );
  1091         TPtrC8 ptr( &aData[start], end - start + 1 );
  1092         TBuf8< KDCFKeySize > key;
  1092         TBuf8< KDCFKeySize > key;
  1093         key.SetLength(KDCFKeySize);
  1093         key.SetLength(KDCFKeySize);
  1094         RPointerArray< CDRMRights > rights;
  1094         RPointerArray< CDRMRights > rights;
  1095         
  1095 
  1096         TCleanupItem cleanup( DoResetAndDestroy, &rights );
  1096         TCleanupItem cleanup( DoResetAndDestroy, &rights );
  1097         CleanupStack::PushL( cleanup );
  1097         CleanupStack::PushL( cleanup );
  1098         
  1098 
  1099         User::LeaveIfError( client.Connect() );
  1099         User::LeaveIfError( client.Connect() );
  1100         CleanupClosePushL( client );
  1100         CleanupClosePushL( client );
  1101         
  1101 
  1102         parser = CDrmRightsParser::NewL();
  1102         parser = CDrmRightsParser::NewL();
  1103         CleanupStack::PushL( parser );
  1103         CleanupStack::PushL( parser );
  1104         
  1104 
  1105         parser->ParseL( ptr, rights );
  1105         parser->ParseL( ptr, rights );
  1106         
  1106 
  1107         if (rights.Count()==0)
  1107         if (rights.Count()==0)
  1108         	{
  1108             {
  1109         	User::Leave(KErrCorrupt);
  1109             User::Leave(KErrCorrupt);
  1110         	}
  1110             }
  1111         
  1111 
  1112         client.GetRandomDataL(key);
  1112         client.GetRandomDataL(key);
  1113 
  1113 
  1114         User::LeaveIfError( client.AddRecord(
  1114         User::LeaveIfError( client.AddRecord(
  1115                             key, 
  1115                             key,
  1116                             rights[0]->GetPermission(), 
  1116                             rights[0]->GetPermission(),
  1117                             aCID, 
  1117                             aCID,
  1118                             localID) );
  1118                             localID) );
  1119         
  1119 
  1120         iRightsObject = CDRMRights::NewL();
  1120         iRightsObject = CDRMRights::NewL();
  1121         
  1121 
  1122         asset = CDRMAsset::NewLC();
  1122         asset = CDRMAsset::NewLC();
  1123         asset->iUid = aCID.AllocL();
  1123         asset->iUid = aCID.AllocL();
  1124         
  1124 
  1125         iRightsObject->SetAssetL(*asset);
  1125         iRightsObject->SetAssetL(*asset);
  1126         iRightsObject->SetPermissionL(rights[0]->GetPermission());
  1126         iRightsObject->SetPermissionL(rights[0]->GetPermission());
  1127         
  1127 
  1128         CleanupStack::PopAndDestroy( 4 ); // asset, parser, client, rights
  1128         CleanupStack::PopAndDestroy( 4 ); // asset, parser, client, rights
  1129         }
  1129         }
  1130     else
  1130     else
  1131         {
  1131         {
  1132         SetBrokenStateL( KErrArgument );
  1132         SetBrokenStateL( KErrArgument );
  1133         }
  1133         }
  1134     }
  1134     }
  1135 
  1135 
  1136 // -----------------------------------------------------------------------------
  1136 // -----------------------------------------------------------------------------
  1137 // CDRMMessageParser::ProcessContentDataL
  1137 // CDRMMessageParser::ProcessContentDataL
  1138 // Handle DCF file's CID manipulation in "DCF in DRM message" case. 
  1138 // Handle DCF file's CID manipulation in "DCF in DRM message" case.
  1139 // Send the data to EncryptUpdateL if encryption is needed.
  1139 // Send the data to EncryptUpdateL if encryption is needed.
  1140 // -----------------------------------------------------------------------------
  1140 // -----------------------------------------------------------------------------
  1141 //
  1141 //
  1142 void CDRMMessageParser::ProcessContentDataL( TPtrC8& aData )
  1142 void CDRMMessageParser::ProcessContentDataL( TPtrC8& aData )
  1143     {
  1143     {
  1163 // -----------------------------------------------------------------------------
  1163 // -----------------------------------------------------------------------------
  1164 //
  1164 //
  1165 TBool CDRMMessageParser::ValidB64CharL( const TUint8 aChar )
  1165 TBool CDRMMessageParser::ValidB64CharL( const TUint8 aChar )
  1166     {
  1166     {
  1167     // Allowed characters are '0'...'9', 'A'...'Z', 'a'...'z', '+', '/', '='
  1167     // Allowed characters are '0'...'9', 'A'...'Z', 'a'...'z', '+', '/', '='
  1168     if ( ( aChar >= 48 && aChar <= 57 ) || 
  1168     if ( ( aChar >= 48 && aChar <= 57 ) ||
  1169          ( aChar >= 65 && aChar <= 90 ) ||
  1169          ( aChar >= 65 && aChar <= 90 ) ||
  1170          ( aChar >= 97 && aChar <= 122 ) || 
  1170          ( aChar >= 97 && aChar <= 122 ) ||
  1171          ( aChar == 43 ) ||
  1171          ( aChar == 43 ) ||
  1172          ( aChar == 47 ) ||
  1172          ( aChar == 47 ) ||
  1173          ( aChar == 61 ) )
  1173          ( aChar == 61 ) )
  1174         {
  1174         {
  1175         return ETrue;
  1175         return ETrue;
  1176         }
  1176         }
  1177 
  1177 
  1178     if ( ( aChar != 0x0D ) && ( aChar != 0x0A ) )
  1178     if ( ( aChar != 0x0D ) && ( aChar != 0x0A ) )
  1179         {
  1179         {
  1180         SetBrokenStateL( KDRMMessageMalformed );        
  1180         SetBrokenStateL( KDRMMessageMalformed );
  1181         }
  1181         }
  1182 
  1182 
  1183     return EFalse;
  1183     return EFalse;
  1184     }
  1184     }
  1185 
  1185 
  1186 // -----------------------------------------------------------------------------
  1186 // -----------------------------------------------------------------------------
  1187 // DRMCommon::ProcessMessage
  1187 // DRMCommon::ProcessMessage
  1188 // 
  1188 //
  1189 // -----------------------------------------------------------------------------
  1189 // -----------------------------------------------------------------------------
  1190 EXPORT_C TInt CDRMMessageParser::ProcessMessage(
  1190 EXPORT_C TInt CDRMMessageParser::ProcessMessage(
  1191     HBufC8*& aDRMMessage)
  1191     HBufC8*& aDRMMessage)
  1192     {
  1192     {
  1193     TInt error( KErrNone );
  1193     TInt error( KErrNone );
  1194     TRAP( error, DoProcessMessageL( aDRMMessage ) );
  1194     TRAP( error, DoProcessMessageL( aDRMMessage ) );
  1195     
  1195 
  1196     return error;
  1196     return error;
  1197     }
  1197     }
  1198     
  1198 
  1199 // -----------------------------------------------------------------------------
  1199 // -----------------------------------------------------------------------------
  1200 // DRMCommon::ProcessRightsObject
  1200 // DRMCommon::ProcessRightsObject
  1201 // Processes a rights objects and saves it in the rights database.
  1201 // Processes a rights objects and saves it in the rights database.
  1202 // -----------------------------------------------------------------------------
  1202 // -----------------------------------------------------------------------------
  1203 EXPORT_C TInt CDRMMessageParser::ProcessRightsObject(
  1203 EXPORT_C TInt CDRMMessageParser::ProcessRightsObject(
  1204     const TDesC8& aRightsObject, 
  1204     const TDesC8& aRightsObject,
  1205     RPointerArray<CDRMRights>& aRightsDetail)
  1205     RPointerArray<CDRMRights>& aRightsDetail)
  1206     {
  1206     {
  1207     TInt error( KErrNone );
  1207     TInt error( KErrNone );
  1208     TRAP( error, DoProcessRightsObjectL( aRightsObject,
  1208     TRAP( error, DoProcessRightsObjectL( aRightsObject,
  1209                                          aRightsDetail ) );
  1209                                          aRightsDetail ) );
  1210                                          
  1210 
  1211     return error;
  1211     return error;
  1212     }
  1212     }
  1213 
  1213 
  1214 void CDRMMessageParser::SetBit( TUint32 aBit )
  1214 void CDRMMessageParser::SetBit( TUint32 aBit )
  1215     {
  1215     {
  1216     iState |= aBit;
  1216     iState |= aBit;
  1217     }
  1217     }
  1218     
  1218 
  1219 void CDRMMessageParser::ClearBit( TUint32 aBit )
  1219 void CDRMMessageParser::ClearBit( TUint32 aBit )
  1220     {
  1220     {
  1221     iState &= ~aBit;
  1221     iState &= ~aBit;
  1222     }
  1222     }
  1223 
  1223 
  1224 void CDRMMessageParser::Reset()
  1224 void CDRMMessageParser::Reset()
  1225     {
  1225     {
  1226     delete iDCFBuffer;
  1226     delete iDCFBuffer;
  1227     iDCFBuffer = NULL;
  1227     iDCFBuffer = NULL;
  1228     
  1228 
  1229     delete iDcfCreator;
  1229     delete iDcfCreator;
  1230     iDcfCreator = NULL;
  1230     iDcfCreator = NULL;
  1231     
  1231 
  1232     delete iRightsData;
  1232     delete iRightsData;
  1233     iRightsData = NULL;
  1233     iRightsData = NULL;
  1234     
  1234 
  1235     delete iRightsObject;
  1235     delete iRightsObject;
  1236     iRightsObject = NULL;
  1236     iRightsObject = NULL;
  1237     
  1237 
  1238     delete iBoundary;
  1238     delete iBoundary;
  1239     iBoundary = NULL;
  1239     iBoundary = NULL;
  1240     
  1240 
  1241     delete iContentType;
  1241     delete iContentType;
  1242     iContentType = NULL;
  1242     iContentType = NULL;
  1243     
  1243 
  1244     iInputBuffer.SetLength( 0 );
  1244     iInputBuffer.SetLength( 0 );
  1245     
  1245 
  1246     iState = ESearchingBoundary;
  1246     iState = ESearchingBoundary;
  1247     iDCFHeaderSize[ 0 ] = KMaxTUint32;
  1247     iDCFHeaderSize[ 0 ] = KMaxTUint32;
  1248     iDCFHeaderSize[ 1 ] = KMaxTUint32;
  1248     iDCFHeaderSize[ 1 ] = KMaxTUint32;
  1249     }
  1249     }
  1250 
  1250 
  1252     {
  1252     {
  1253     TDeleteFileData fileData;
  1253     TDeleteFileData fileData;
  1254     RFileWriteStream output;
  1254     RFileWriteStream output;
  1255     RFile file;
  1255     RFile file;
  1256     TInt size( 0 );
  1256     TInt size( 0 );
  1257     
  1257 
  1258     User::LeaveIfError( fileData.aFs.Connect() );
  1258     User::LeaveIfError( fileData.aFs.Connect() );
  1259     CleanupClosePushL( fileData.aFs );
  1259     CleanupClosePushL( fileData.aFs );
  1260 
  1260 
  1261     TCleanupItem cleanup( DoDeleteFile, &fileData );
  1261     TCleanupItem cleanup( DoDeleteFile, &fileData );
  1262     CleanupStack::PushL( cleanup );
  1262     CleanupStack::PushL( cleanup );
  1263     
  1263 
  1264 #ifndef RD_MULTIPLE_DRIVE
  1264 #ifndef RD_MULTIPLE_DRIVE
  1265 
  1265 
  1266     User::LeaveIfError( output.Temp( fileData.aFs, 
  1266     User::LeaveIfError( output.Temp( fileData.aFs,
  1267                                      KTempPath, 
  1267                                      KTempPath,
  1268                                      fileData.aName, 
  1268                                      fileData.aName,
  1269                                      EFileWrite ) );
  1269                                      EFileWrite ) );
  1270     
  1270 
  1271 #else //RD_MULTIPLE_DRIVE
  1271 #else //RD_MULTIPLE_DRIVE
  1272     
  1272 
  1273     TInt driveNumber( -1 );
  1273     TInt driveNumber( -1 );
  1274     TChar driveLetter;
  1274     TChar driveLetter;
  1275     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
  1275     DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber );
  1276 	fileData.aFs.DriveToChar( driveNumber, driveLetter );
  1276     fileData.aFs.DriveToChar( driveNumber, driveLetter );
  1277     
  1277 
  1278 	TFileName tempPath;
  1278     TFileName tempPath;
  1279 	tempPath.Format( KTempPath, (TUint)driveLetter );
  1279     tempPath.Format( KTempPath, (TUint)driveLetter );
  1280 
  1280 
  1281     User::LeaveIfError( output.Temp( fileData.aFs, 
  1281     User::LeaveIfError( output.Temp( fileData.aFs,
  1282                                    tempPath, 
  1282                                    tempPath,
  1283                                    fileData.aName, 
  1283                                    fileData.aName,
  1284                                    EFileWrite ) );
  1284                                    EFileWrite ) );
  1285     
  1285 
  1286 #endif
  1286 #endif
  1287     
  1287 
  1288     CleanupClosePushL( output );
  1288     CleanupClosePushL( output );
  1289     
  1289 
  1290     InitializeMessageParserL( output );
  1290     InitializeMessageParserL( output );
  1291     ProcessMessageDataL( *aDRMMessage );
  1291     ProcessMessageDataL( *aDRMMessage );
  1292     FinalizeMessageParserL();
  1292     FinalizeMessageParserL();
  1293     
  1293 
  1294     CleanupStack::PopAndDestroy(); // output
  1294     CleanupStack::PopAndDestroy(); // output
  1295     
  1295 
  1296     User::LeaveIfError( file.Open( fileData.aFs, fileData.aName, EFileRead ) );
  1296     User::LeaveIfError( file.Open( fileData.aFs, fileData.aName, EFileRead ) );
  1297     CleanupClosePushL( file );
  1297     CleanupClosePushL( file );
  1298     
  1298 
  1299     User::LeaveIfError( file.Size( size ) );
  1299     User::LeaveIfError( file.Size( size ) );
  1300     
  1300 
  1301     if ( size > aDRMMessage->Des().MaxSize() )
  1301     if ( size > aDRMMessage->Des().MaxSize() )
  1302         {
  1302         {
  1303         HBufC8* tmp( NULL );
  1303         HBufC8* tmp( NULL );
  1304         
  1304 
  1305         delete aDRMMessage; 
  1305         delete aDRMMessage;
  1306         aDRMMessage = NULL;
  1306         aDRMMessage = NULL;
  1307         
  1307 
  1308         tmp = HBufC8::NewLC( size );
  1308         tmp = HBufC8::NewLC( size );
  1309         TPtr8 data( tmp->Des() );
  1309         TPtr8 data( tmp->Des() );
  1310         
  1310 
  1311         User::LeaveIfError( file.Read( data ) );
  1311         User::LeaveIfError( file.Read( data ) );
  1312         CleanupStack::Pop(); // tmp
  1312         CleanupStack::Pop(); // tmp
  1313         
  1313 
  1314         aDRMMessage = tmp;
  1314         aDRMMessage = tmp;
  1315         }
  1315         }
  1316     else
  1316     else
  1317         {
  1317         {
  1318         TPtr8 data( aDRMMessage->Des() );
  1318         TPtr8 data( aDRMMessage->Des() );
  1319         User::LeaveIfError( file.Read( data ) );
  1319         User::LeaveIfError( file.Read( data ) );
  1320         }
  1320         }
  1321     
  1321 
  1322     CleanupStack::PopAndDestroy( 3 ); // file, cleanup, fileData.aFs
  1322     CleanupStack::PopAndDestroy( 3 ); // file, cleanup, fileData.aFs
  1323     }
  1323     }
  1324 
  1324 
  1325 void CDRMMessageParser::DoProcessRightsObjectL( 
  1325 void CDRMMessageParser::DoProcessRightsObjectL(
  1326     const TDesC8& aRightsObject, 
  1326     const TDesC8& aRightsObject,
  1327     RPointerArray<CDRMRights>& aRightsDetail )
  1327     RPointerArray<CDRMRights>& aRightsDetail )
  1328     {
  1328     {
  1329     CDrmRightsParser* parser = NULL;
  1329     CDrmRightsParser* parser = NULL;
  1330     TInt start;
  1330     TInt start;
  1331     TInt end;
  1331     TInt end;
  1332     TPtrC8 ptr(0, 0);
  1332     TPtrC8 ptr(0, 0);
  1333     
  1333 
  1334     start = aRightsObject.Find(KRightsStartTag);
  1334     start = aRightsObject.Find(KRightsStartTag);
  1335     end = aRightsObject.LocateReverse('>');
  1335     end = aRightsObject.LocateReverse('>');
  1336     
  1336 
  1337     TCleanupItem cleanup( DoResetAndDestroy, &aRightsDetail );
  1337     TCleanupItem cleanup( DoResetAndDestroy, &aRightsDetail );
  1338     CleanupStack::PushL( cleanup );
  1338     CleanupStack::PushL( cleanup );
  1339 
  1339 
  1340     if ( start != KErrNotFound && end != KErrNotFound )
  1340     if ( start != KErrNotFound && end != KErrNotFound )
  1341         {
  1341         {
  1342         // xml
  1342         // xml
  1343         parser = CDrmRightsParser::NewL();
  1343         parser = CDrmRightsParser::NewL();
  1344         CleanupStack::PushL(parser);
  1344         CleanupStack::PushL(parser);
  1345         
  1345 
  1346         ptr.Set(&aRightsObject[start], end - start + 1);    
  1346         ptr.Set(&aRightsObject[start], end - start + 1);
  1347         
  1347 
  1348         parser->ParseAndStoreL(ptr, aRightsDetail);
  1348         parser->ParseAndStoreL(ptr, aRightsDetail);
  1349         
  1349 
  1350         if (aRightsDetail.Count() == 0)
  1350         if (aRightsDetail.Count() == 0)
  1351             {
  1351             {
  1352             User::Leave( KErrArgument );
  1352             User::Leave( KErrArgument );
  1353             }
  1353             }
  1354         
  1354 
  1355         CleanupStack::PopAndDestroy(); // parser
  1355         CleanupStack::PopAndDestroy(); // parser
  1356         }
  1356         }
  1357     else if (start == KErrNotFound )
  1357     else if (start == KErrNotFound )
  1358         {
  1358         {
  1359         // wbxml
  1359         // wbxml
  1360         parser = CDrmRightsParser::NewL(CDrmRightsParser::EWbxmlParser);
  1360         parser = CDrmRightsParser::NewL(CDrmRightsParser::EWbxmlParser);
  1361         CleanupStack::PushL(parser);
  1361         CleanupStack::PushL(parser);
  1362         
  1362 
  1363         parser->ParseAndStoreL(aRightsObject, aRightsDetail);
  1363         parser->ParseAndStoreL(aRightsObject, aRightsDetail);
  1364         if (aRightsDetail.Count() == 0)
  1364         if (aRightsDetail.Count() == 0)
  1365             {
  1365             {
  1366             User::Leave( KErrArgument );
  1366             User::Leave( KErrArgument );
  1367             }
  1367             }
  1368         
  1368 
  1369         CleanupStack::PopAndDestroy(); // parser
  1369         CleanupStack::PopAndDestroy(); // parser
  1370         }
  1370         }
  1371     else
  1371     else
  1372         {
  1372         {
  1373         User::Leave( KErrArgument );
  1373         User::Leave( KErrArgument );
  1374         }
  1374         }
  1375     
  1375 
  1376     CleanupStack::Pop(); // cleanup
  1376     CleanupStack::Pop(); // cleanup
  1377     }
  1377     }
  1378     
  1378 
  1379 void CDRMMessageParser::DeletePermission()
  1379 void CDRMMessageParser::DeletePermission()
  1380     {
  1380     {
  1381     if ( iRightsObject )
  1381     if ( iRightsObject )
  1382         {
  1382         {
  1383         if ( !( iState & EFLContent ) )
  1383         if ( !( iState & EFLContent ) )
  1384             {
  1384             {
  1385             HBufC8* URI = NULL;
  1385             HBufC8* URI = NULL;
  1386             
  1386 
  1387             if ( !( iRightsObject->GetContentURI( URI ) ) )
  1387             if ( !( iRightsObject->GetContentURI( URI ) ) )
  1388                 {
  1388                 {
  1389                 __ASSERT_DEBUG( URI, User::Invariant() );
  1389                 __ASSERT_DEBUG( URI, User::Invariant() );
  1390                 
  1390 
  1391                 RDRMRightsClient client;
  1391                 RDRMRightsClient client;
  1392                 
  1392 
  1393                 TInt error = client.Connect();
  1393                 TInt error = client.Connect();
  1394                 
  1394 
  1395                 if ( !error )
  1395                 if ( !error )
  1396                     {
  1396                     {
  1397                     // Don't care if it fails.
  1397                     // Don't care if it fails.
  1398                     client.DeleteDbEntry( *URI, iRightsObject->GetLocalID() );
  1398                     client.DeleteDbEntry( *URI, iRightsObject->GetLocalID() );
  1399                     
  1399 
  1400                     client.Close();
  1400                     client.Close();
  1401                     }
  1401                     }
  1402                 
  1402 
  1403                 delete URI;
  1403                 delete URI;
  1404                 URI = NULL;
  1404                 URI = NULL;
  1405                 }
  1405                 }
  1406             }
  1406             }
  1407         
  1407 
  1408         delete iRightsObject;
  1408         delete iRightsObject;
  1409         iRightsObject = NULL;
  1409         iRightsObject = NULL;
  1410         }
  1410         }
  1411     }
  1411     }
  1412 
  1412 
  1413 void CDRMMessageParser::SetBrokenStateL( const TInt aError )
  1413 void CDRMMessageParser::SetBrokenStateL( const TInt aError )
  1414     {
  1414     {
  1415     SetBit( EBroken );
  1415     SetBit( EBroken );
  1416     DeletePermission();
  1416     DeletePermission();
  1417     
  1417 
  1418     User::Leave( aError );
  1418     User::Leave( aError );
  1419     }
  1419     }
  1420 
  1420 
  1421 void CDRMMessageParser::InitDCFBufferL()
  1421 void CDRMMessageParser::InitDCFBufferL()
  1422     {
  1422     {
  1440     User::LeaveIfError( client.Connect() );
  1440     User::LeaveIfError( client.Connect() );
  1441     client.GetRandomDataL(id);
  1441     client.GetRandomDataL(id);
  1442     CleanupStack::PopAndDestroy();
  1442     CleanupStack::PopAndDestroy();
  1443 
  1443 
  1444     des = KFLPrefix;
  1444     des = KFLPrefix;
  1445     
  1445 
  1446     for (TInt i = 0; i < KCDPlainIDLength; i++)
  1446     for (TInt i = 0; i < KCDPlainIDLength; i++)
  1447         {
  1447         {
  1448         des.AppendNumFixedWidth( id[i], EDecimal, 1 );
  1448         des.AppendNumFixedWidth( id[i], EDecimal, 1 );
  1449         }
  1449         }
  1450 
  1450 
  1451     des.Append( KFLSuffix );
  1451     des.Append( KFLSuffix );
  1452     }
  1452     }
  1453     
  1453 
  1454 TInt CDRMMessageParser::RetrieveFlRights()
  1454 TInt CDRMMessageParser::RetrieveFlRights()
  1455     {
  1455     {
  1456     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
  1456     __ASSERT_DEBUG( !iRightsObject, User::Invariant() );
  1457     
  1457 
  1458     RDRMRightsClient client;
  1458     RDRMRightsClient client;
  1459     TInt error( client.Connect() );
  1459     TInt error( client.Connect() );
  1460     
  1460 
  1461     if ( !error )
  1461     if ( !error )
  1462         {
  1462         {
  1463         TRAP( error, EnsureFLRightsExistL( client, &iRightsObject ) );
  1463         TRAP( error, EnsureFLRightsExistL( client, &iRightsObject ) );
  1464                 
  1464 
  1465         client.Close();
  1465         client.Close();
  1466         }
  1466         }
  1467         
  1467 
  1468     return error;
  1468     return error;
  1469     }
  1469     }
  1470 
  1470 
  1471 void CDRMMessageParser::ProcessDCFDataL( TPtrC8& aDCFData )
  1471 void CDRMMessageParser::ProcessDCFDataL( TPtrC8& aDCFData )
  1472     {
  1472     {
  1473     TBool doCommit( EFalse );
  1473     TBool doCommit( EFalse );
  1474     
  1474 
  1475     // Loop until all available data is either cached or processed.
  1475     // Loop until all available data is either cached or processed.
  1476     // What happens is
  1476     // What happens is
  1477     // - modify Content-URI
  1477     // - modify Content-URI
  1478     // - modify DCF header part
  1478     // - modify DCF header part
  1479     // - dump the rest of the available data to output.
  1479     // - dump the rest of the available data to output.
  1483             {
  1483             {
  1484             //////////////////////////////////////////////////////////////////
  1484             //////////////////////////////////////////////////////////////////
  1485             // Modify ContentURI.
  1485             // Modify ContentURI.
  1486             //////////////////////////////////////////////////////////////////
  1486             //////////////////////////////////////////////////////////////////
  1487             FillDCFBufferL( aDCFData );
  1487             FillDCFBufferL( aDCFData );
  1488         
  1488 
  1489             if ( iDCFBuffer->Length() > 3 )
  1489             if ( iDCFBuffer->Length() > 3 )
  1490                 {
  1490                 {
  1491                 TInt pos = 0;
  1491                 TInt pos = 0;
  1492                 TUint8* data = const_cast< TUint8* > ( iDCFBuffer->Ptr() );
  1492                 TUint8* data = const_cast< TUint8* > ( iDCFBuffer->Ptr() );
  1493                 
  1493 
  1494                 if ( data[ 0 ] != 1 )
  1494                 if ( data[ 0 ] != 1 )
  1495                     {
  1495                     {
  1496                     SetBrokenStateL( KDRMMessageMalformed );
  1496                     SetBrokenStateL( KDRMMessageMalformed );
  1497                     }
  1497                     }
  1498                 
  1498 
  1499                 // Cache the data until 
  1499                 // Cache the data until
  1500                 // - version, 
  1500                 // - version,
  1501                 // - ContentTypeLen, 
  1501                 // - ContentTypeLen,
  1502                 // - ContentURILen, 
  1502                 // - ContentURILen,
  1503                 // - ContentType and 
  1503                 // - ContentType and
  1504                 // - ContentURI 
  1504                 // - ContentURI
  1505                 // have been received.
  1505                 // have been received.
  1506                 pos = data[ 1 ] + 3;
  1506                 pos = data[ 1 ] + 3;
  1507                 if ( iDCFBuffer->Length() < pos + data[ 2 ] )
  1507                 if ( iDCFBuffer->Length() < pos + data[ 2 ] )
  1508                     {
  1508                     {
  1509                     return;
  1509                     return;
  1510                     }
  1510                     }
  1511                 
  1511 
  1512                 // Sanity check. URI has to be more than four ("cid:") octets.
  1512                 // Sanity check. URI has to be more than four ("cid:") octets.
  1513                 if ( data[ 2 ] < 5 )
  1513                 if ( data[ 2 ] < 5 )
  1514                     {
  1514                     {
  1515                     SetBrokenStateL( KDRMMessageMalformed );
  1515                     SetBrokenStateL( KDRMMessageMalformed );
  1516                     }
  1516                     }
  1517                 
  1517 
  1518                 if ( Mem::CompareF( &data[ pos ], 
  1518                 if ( Mem::CompareF( &data[ pos ],
  1519                                     KCIDStringLength,
  1519                                     KCIDStringLength,
  1520                                     KCIDString().Ptr(), 
  1520                                     KCIDString().Ptr(),
  1521                                     KCIDStringLength ) == 0 )
  1521                                     KCIDStringLength ) == 0 )
  1522                     {
  1522                     {
  1523                     // The data length doesn't change, so Mem::Copy() is safe.
  1523                     // The data length doesn't change, so Mem::Copy() is safe.
  1524                     Mem::Copy( &data[ pos ], 
  1524                     Mem::Copy( &data[ pos ],
  1525                                KFLPrefix().Ptr(), 
  1525                                KFLPrefix().Ptr(),
  1526                                KFLKPrefixLength );
  1526                                KFLKPrefixLength );
  1527                     
  1527 
  1528                     iOutputStream.WriteL( iDCFBuffer->Left( pos + data[ 2 ] ) );
  1528                     iOutputStream.WriteL( iDCFBuffer->Left( pos + data[ 2 ] ) );
  1529                     
  1529 
  1530                     doCommit = ETrue;
  1530                     doCommit = ETrue;
  1531 
  1531 
  1532                     CompressDCFBuffer( pos + data[ 2 ] );
  1532                     CompressDCFBuffer( pos + data[ 2 ] );
  1533                     
  1533 
  1534                     SetBit( EDCFURIModified );
  1534                     SetBit( EDCFURIModified );
  1535                     }
  1535                     }
  1536                 else
  1536                 else
  1537                     {
  1537                     {
  1538                     // Discard the broken DCF
  1538                     // Discard the broken DCF
  1551             // URI is now modified. Modify DCF headers if necessary.
  1551             // URI is now modified. Modify DCF headers if necessary.
  1552             //////////////////////////////////////////////////////////////////
  1552             //////////////////////////////////////////////////////////////////
  1553             if ( !( iState & EDCFHeadersModified ) )
  1553             if ( !( iState & EDCFHeadersModified ) )
  1554                 {
  1554                 {
  1555                 FillDCFBufferL( aDCFData );
  1555                 FillDCFBufferL( aDCFData );
  1556                 
  1556 
  1557                 // Figure out how much data there is in the header part and/or
  1557                 // Figure out how much data there is in the header part and/or
  1558                 // in the data part.
  1558                 // in the data part.
  1559                 if ( ( iDCFHeaderSize[ 0 ] == KMaxTUint32 ) &&
  1559                 if ( ( iDCFHeaderSize[ 0 ] == KMaxTUint32 ) &&
  1560                      ( iDCFHeaderSize[ 1 ] == KMaxTUint32 ) )
  1560                      ( iDCFHeaderSize[ 1 ] == KMaxTUint32 ) )
  1561                     {
  1561                     {
  1562                     TUint8 used( 0 );
  1562                     TUint8 used( 0 );
  1563                     
  1563 
  1564                     // uintvar has 1...5 octets and we need two uintvars before
  1564                     // uintvar has 1...5 octets and we need two uintvars before
  1565                     // anything can be done. Still, there has to be at least 
  1565                     // anything can be done. Still, there has to be at least
  1566                     // 12 octets of data in total to make the DCF legal. But here
  1566                     // 12 octets of data in total to make the DCF legal. But here
  1567                     // we just check the two uintvars.
  1567                     // we just check the two uintvars.
  1568                     if ( iDCFBuffer->Length() < 10 )
  1568                     if ( iDCFBuffer->Length() < 10 )
  1569                         {
  1569                         {
  1570                         // Not enough data yet.
  1570                         // Not enough data yet.
  1571                         // No need to flush aDCFData at this point, since it 
  1571                         // No need to flush aDCFData at this point, since it
  1572                         // simply cannot contain anything at this point.
  1572                         // simply cannot contain anything at this point.
  1573                         __ASSERT_DEBUG( !aDCFData.Length(), User::Invariant() );
  1573                         __ASSERT_DEBUG( !aDCFData.Length(), User::Invariant() );
  1574                         break;
  1574                         break;
  1575                         }
  1575                         }
  1576                     
  1576 
  1577                     // Read header field length & data length.
  1577                     // Read header field length & data length.
  1578                     for ( TUint8 count = 0; count < 2; ++count )
  1578                     for ( TUint8 count = 0; count < 2; ++count )
  1579                         {
  1579                         {
  1580                         TInt size( 0 );
  1580                         TInt size( 0 );
  1581                         
  1581 
  1582                         TWspPrimitiveDecoder decoder( 
  1582                         TWspPrimitiveDecoder decoder(
  1583                                 iDCFBuffer->Mid( used ) );
  1583                                 iDCFBuffer->Mid( used ) );
  1584                         size = decoder.UintVar( iDCFHeaderSize[ count ] );
  1584                         size = decoder.UintVar( iDCFHeaderSize[ count ] );
  1585                         
  1585 
  1586                         // Sanity check.
  1586                         // Sanity check.
  1587                         if ( size < 1 || iDCFHeaderSize[ count ] >= KMaxTInt )
  1587                         if ( size < 1 || iDCFHeaderSize[ count ] >= KMaxTInt )
  1588                             {
  1588                             {
  1589                             SetBrokenStateL( KDRMMessageMalformed );
  1589                             SetBrokenStateL( KDRMMessageMalformed );
  1590                             }
  1590                             }
  1591                         
  1591 
  1592                         used += size;
  1592                         used += size;
  1593                         }
  1593                         }
  1594                     
  1594 
  1595                     CompressDCFBuffer( used );
  1595                     CompressDCFBuffer( used );
  1596                     }
  1596                     }
  1597                 else
  1597                 else
  1598                     {
  1598                     {
  1599                     // We know the original header size now.
  1599                     // We know the original header size now.
  1600                     // Wait until the whole header is read.
  1600                     // Wait until the whole header is read.
  1601                     if ( static_cast< TUint32 >( iDCFBuffer->Length() ) < 
  1601                     if ( static_cast< TUint32 >( iDCFBuffer->Length() ) <
  1602                          iDCFHeaderSize[ 0 ] )
  1602                          iDCFHeaderSize[ 0 ] )
  1603                         {
  1603                         {
  1604                         if ( !aDCFData.Length() )
  1604                         if ( !aDCFData.Length() )
  1605                             {
  1605                             {
  1606                             // All available data is now processed.
  1606                             // All available data is now processed.
  1611                         {
  1611                         {
  1612                         TUint offset( 0 );
  1612                         TUint offset( 0 );
  1613                         TUint length( 0 );
  1613                         TUint length( 0 );
  1614                         HBufC8* newHeader = NULL;
  1614                         HBufC8* newHeader = NULL;
  1615 
  1615 
  1616                         if ( FindDCFHeader( KRightsIssuer, 
  1616                         if ( FindDCFHeader( KRightsIssuer,
  1617                                             offset, 
  1617                                             offset,
  1618                                             length ) )
  1618                                             length ) )
  1619                             {
  1619                             {
  1620                             // The header field exists.
  1620                             // The header field exists.
  1621                             TInt pos( 0 );
  1621                             TInt pos( 0 );
  1622                             TPtr8 trim( const_cast< TUint8* >( 
  1622                             TPtr8 trim( const_cast< TUint8* >(
  1623                                             iDCFBuffer->Ptr() ) + offset,
  1623                                             iDCFBuffer->Ptr() ) + offset,
  1624                                             length, 
  1624                                             length,
  1625                                             length );
  1625                                             length );
  1626 
  1626 
  1627                             iDCFHeaderSize[ 0 ] -= length; // remove old data.
  1627                             iDCFHeaderSize[ 0 ] -= length; // remove old data.
  1628                             
  1628 
  1629                             // No colon, no header value. 
  1629                             // No colon, no header value.
  1630                             pos = trim.Find( KColon );
  1630                             pos = trim.Find( KColon );
  1631                             if ( pos > 0 )
  1631                             if ( pos > 0 )
  1632                                 {
  1632                                 {
  1633                                 trim.Set( const_cast< TUint8* >( trim.Ptr() ) + pos + 1, 
  1633                                 trim.Set( const_cast< TUint8* >( trim.Ptr() ) + pos + 1,
  1634                                           trim.Length() - pos - 1,
  1634                                           trim.Length() - pos - 1,
  1635                                           trim.Length() - pos - 1 );
  1635                                           trim.Length() - pos - 1 );
  1636 
  1636 
  1637                                 // Skip whitespaces
  1637                                 // Skip whitespaces
  1638                                 trim.TrimLeft();
  1638                                 trim.TrimLeft();
  1639                                 trim.TrimRight();
  1639                                 trim.TrimRight();
  1640                                 
  1640 
  1641                                 if ( trim.Length() )
  1641                                 if ( trim.Length() )
  1642                                     {
  1642                                     {
  1643                                     // Something to process
  1643                                     // Something to process
  1644                                     newHeader = EncryptDCFFieldLC( trim );
  1644                                     newHeader = EncryptDCFFieldLC( trim );
  1645                                     
  1645 
  1646                                     iDCFHeaderSize[ 0 ] += KRightsIssuer().Length();
  1646                                     iDCFHeaderSize[ 0 ] += KRightsIssuer().Length();
  1647                                     iDCFHeaderSize[ 0 ] += newHeader->Length();
  1647                                     iDCFHeaderSize[ 0 ] += newHeader->Length();
  1648                                     iDCFHeaderSize[ 0 ] += 3; // ":" and CRLF
  1648                                     iDCFHeaderSize[ 0 ] += 3; // ":" and CRLF
  1649                                     }
  1649                                     }
  1650                                 }
  1650                                 }
  1651                             }
  1651                             }
  1652                         
  1652 
  1653                         // Write the uintvars to output.
  1653                         // Write the uintvars to output.
  1654                         for ( TUint8 loop = 0; loop < 2; ++loop )
  1654                         for ( TUint8 loop = 0; loop < 2; ++loop )
  1655                             {
  1655                             {
  1656                             TWspPrimitiveEncoder encoder;
  1656                             TWspPrimitiveEncoder encoder;
  1657                             HBufC8* var( encoder.UintVarL( iDCFHeaderSize[ loop ] ) );
  1657                             HBufC8* var( encoder.UintVarL( iDCFHeaderSize[ loop ] ) );
  1658                             
  1658 
  1659                             CleanupStack::PushL( var );
  1659                             CleanupStack::PushL( var );
  1660                             
  1660 
  1661                             iOutputStream.WriteL( *var );
  1661                             iOutputStream.WriteL( *var );
  1662                             
  1662 
  1663                             CleanupStack::PopAndDestroy(); // var
  1663                             CleanupStack::PopAndDestroy(); // var
  1664                             }
  1664                             }
  1665                         
  1665 
  1666                         // Dump the header data to output stream.
  1666                         // Dump the header data to output stream.
  1667                         iOutputStream.WriteL( iDCFBuffer->Left( offset ) );
  1667                         iOutputStream.WriteL( iDCFBuffer->Left( offset ) );
  1668                         
  1668 
  1669                         if ( newHeader )
  1669                         if ( newHeader )
  1670                             {
  1670                             {
  1671                             iOutputStream.WriteL( KRightsIssuer );
  1671                             iOutputStream.WriteL( KRightsIssuer );
  1672                             iOutputStream.WriteL( KColon );
  1672                             iOutputStream.WriteL( KColon );
  1673                             iOutputStream.WriteL( *newHeader );
  1673                             iOutputStream.WriteL( *newHeader );
  1674                             
  1674 
  1675                             CleanupStack::PopAndDestroy(); // newHeader
  1675                             CleanupStack::PopAndDestroy(); // newHeader
  1676                             newHeader = NULL;
  1676                             newHeader = NULL;
  1677                             
  1677 
  1678                             iOutputStream.WriteL( KEndLine );
  1678                             iOutputStream.WriteL( KEndLine );
  1679                             }
  1679                             }
  1680 
  1680 
  1681                         iOutputStream.WriteL( 
  1681                         iOutputStream.WriteL(
  1682                             iDCFBuffer->Right( iDCFBuffer->Length() - 
  1682                             iDCFBuffer->Right( iDCFBuffer->Length() -
  1683                                                 offset - 
  1683                                                 offset -
  1684                                                 length ) );
  1684                                                 length ) );
  1685                         
  1685 
  1686                         doCommit = ETrue;
  1686                         doCommit = ETrue;
  1687                         
  1687 
  1688                         CompressDCFBuffer( iDCFBuffer->Length() );
  1688                         CompressDCFBuffer( iDCFBuffer->Length() );
  1689                         SetBit( EDCFHeadersModified );
  1689                         SetBit( EDCFHeadersModified );
  1690                         }
  1690                         }
  1691                     }
  1691                     }
  1692                 }
  1692                 }
  1694                 {
  1694                 {
  1695                 // Dump the rest of the data.
  1695                 // Dump the rest of the data.
  1696                 __ASSERT_DEBUG( !( iDCFBuffer->Length() ), User::Invariant() );
  1696                 __ASSERT_DEBUG( !( iDCFBuffer->Length() ), User::Invariant() );
  1697 
  1697 
  1698                 iOutputStream.WriteL( aDCFData );
  1698                 iOutputStream.WriteL( aDCFData );
  1699                 
  1699 
  1700                 aDCFData.Set( NULL, 0 );
  1700                 aDCFData.Set( NULL, 0 );
  1701                 
  1701 
  1702                 doCommit = ETrue;
  1702                 doCommit = ETrue;
  1703                 }
  1703                 }
  1704             }
  1704             }
  1705         }
  1705         }
  1706 
  1706 
  1716         {
  1716         {
  1717         TInt size( 0 );
  1717         TInt size( 0 );
  1718 
  1718 
  1719         if ( iDCFBuffer->Length() == iDCFBuffer->Des().MaxSize() )
  1719         if ( iDCFBuffer->Length() == iDCFBuffer->Des().MaxSize() )
  1720             {
  1720             {
  1721             HBufC8* ptr = iDCFBuffer->ReAlloc( iDCFBuffer->Length() + 
  1721             HBufC8* ptr = iDCFBuffer->ReAlloc( iDCFBuffer->Length() +
  1722                             KDefaultInputBufferSize );
  1722                             KDefaultInputBufferSize );
  1723 
  1723 
  1724             if ( !ptr )
  1724             if ( !ptr )
  1725                 {
  1725                 {
  1726                 SetBrokenStateL( KErrNoMemory );
  1726                 SetBrokenStateL( KErrNoMemory );
  1727                 }
  1727                 }
  1728 
  1728 
  1729             iDCFBuffer = ptr;
  1729             iDCFBuffer = ptr;
  1730             }
  1730             }
  1731         
  1731 
  1732         size = Min( iDCFBuffer->Des().MaxSize() - iDCFBuffer->Length(), 
  1732         size = Min( iDCFBuffer->Des().MaxSize() - iDCFBuffer->Length(),
  1733                     aData.Length() );
  1733                     aData.Length() );
  1734         
  1734 
  1735         iDCFBuffer->Des().Append( aData.Left( size ) );
  1735         iDCFBuffer->Des().Append( aData.Left( size ) );
  1736         
  1736 
  1737         aData.Set( aData.Right( aData.Length() - size ) );
  1737         aData.Set( aData.Right( aData.Length() - size ) );
  1738         }
  1738         }
  1739     }
  1739     }
  1740     
  1740 
  1741 void CDRMMessageParser::CompressDCFBuffer( const TInt aHowMuch )
  1741 void CDRMMessageParser::CompressDCFBuffer( const TInt aHowMuch )
  1742     {
  1742     {
  1743     __ASSERT_DEBUG( aHowMuch <= iDCFBuffer->Des().MaxSize(), User::Invariant() );
  1743     __ASSERT_DEBUG( aHowMuch <= iDCFBuffer->Des().MaxSize(), User::Invariant() );
  1744 
  1744 
  1745     *iDCFBuffer = iDCFBuffer->Des().Mid( aHowMuch );
  1745     *iDCFBuffer = iDCFBuffer->Des().Mid( aHowMuch );
  1746     }
  1746     }
  1747     TBool CDRMMessageParser::FindDCFHeader( const TDesC8& aString,
  1747     TBool CDRMMessageParser::FindDCFHeader( const TDesC8& aString,
  1748                                         TUint& aOffset,
  1748                                         TUint& aOffset,
  1749                                         TUint& aLength )
  1749                                         TUint& aLength )
  1750     {
  1750     {
  1751     TPtrC8 des( const_cast< TUint8* >( iDCFBuffer->Ptr() ),  
  1751     TPtrC8 des( const_cast< TUint8* >( iDCFBuffer->Ptr() ),
  1752                 Min( iDCFBuffer->Length(), iDCFHeaderSize[ 0 ] ) );
  1752                 Min( iDCFBuffer->Length(), iDCFHeaderSize[ 0 ] ) );
  1753 
  1753 
  1754     aOffset = 0;
  1754     aOffset = 0;
  1755     aLength = 0;
  1755     aLength = 0;
  1756 
  1756 
  1768             }
  1768             }
  1769         else
  1769         else
  1770             {
  1770             {
  1771             pos += KEndLineLength;
  1771             pos += KEndLineLength;
  1772             }
  1772             }
  1773             
  1773 
  1774         if ( ( pos < aString.Length() ) || 
  1774         if ( ( pos < aString.Length() ) ||
  1775              ( des.Left( aString.Length() ).CompareF( aString ) != 0 ) )
  1775              ( des.Left( aString.Length() ).CompareF( aString ) != 0 ) )
  1776              {
  1776              {
  1777             // Skip the line, since this can't be the one we're looking for.
  1777             // Skip the line, since this can't be the one we're looking for.
  1778             des.Set( des.Right( des.Length() - 
  1778             des.Set( des.Right( des.Length() -
  1779                                 pos ) );
  1779                                 pos ) );
  1780             }
  1780             }
  1781         else
  1781         else
  1782             {
  1782             {
  1783             aOffset = des.Ptr() - iDCFBuffer->Ptr();
  1783             aOffset = des.Ptr() - iDCFBuffer->Ptr();
  1784             aLength = pos;
  1784             aLength = pos;
  1785             
  1785 
  1786             return ETrue;
  1786             return ETrue;
  1787             }
  1787             }
  1788         }
  1788         }
  1789     
  1789 
  1790     // Never reached.
  1790     // Never reached.
  1791     return EFalse;
  1791     return EFalse;
  1792     }
  1792     }
  1793     
  1793 
  1794 void CDRMMessageParser::EnsureFLRightsExistL( 
  1794 void CDRMMessageParser::EnsureFLRightsExistL(
  1795     RDRMRightsClient& aClient, 
  1795     RDRMRightsClient& aClient,
  1796     CDRMRights** aOutput )
  1796     CDRMRights** aOutput )
  1797     {
  1797     {
  1798     HBufC8* cid( NULL );
  1798     HBufC8* cid( NULL );
  1799     CDRMRights* perm( NULL );
  1799     CDRMRights* perm( NULL );
  1800     RPointerArray< CDRMPermission > rights( 1 );
  1800     RPointerArray< CDRMPermission > rights( 1 );
  1801     
  1801 
  1802     TCleanupItem cleanup( DoResetAndDestroy2, &rights );
  1802     TCleanupItem cleanup( DoResetAndDestroy2, &rights );
  1803     CleanupStack::PushL( cleanup );
  1803     CleanupStack::PushL( cleanup );
  1804     
  1804 
  1805     User::LeaveIfError( aClient.ForwardLockURI( cid ) );
  1805     User::LeaveIfError( aClient.ForwardLockURI( cid ) );
  1806     CleanupStack::PushL( cid );
  1806     CleanupStack::PushL( cid );
  1807     
  1807 
  1808     TRAPD( error, aClient.GetDBEntriesL( *cid, rights ) );
  1808     TRAPD( error, aClient.GetDBEntriesL( *cid, rights ) );
  1809     
  1809 
  1810     if ( !error )
  1810     if ( !error )
  1811         {
  1811         {
  1812         ConvertPermissionL( perm, *( rights[ 0 ] ), *cid );
  1812         ConvertPermissionL( perm, *( rights[ 0 ] ), *cid );
  1813         // No need to pushl 'perm' into cleanup stack.
  1813         // No need to pushl 'perm' into cleanup stack.
  1814         }
  1814         }
  1815     else if ( error == KErrCANoRights )
  1815     else if ( error == KErrCANoRights )
  1816         {
  1816         {
  1817         HBufC8* fl( NULL );
  1817         HBufC8* fl( NULL );
  1818         RPointerArray< CDRMRights > rightslist( 1 );
  1818         RPointerArray< CDRMRights > rightslist( 1 );
  1819         
  1819 
  1820         TCleanupItem cleanup2( DoResetAndDestroy, &rightslist );
  1820         TCleanupItem cleanup2( DoResetAndDestroy, &rightslist );
  1821         CleanupStack::PushL( cleanup2 );
  1821         CleanupStack::PushL( cleanup2 );
  1822         
  1822 
  1823         fl = HBufC8::NewLC( KFLROSize + cid->Length() );
  1823         fl = HBufC8::NewLC( KFLROSize + cid->Length() );
  1824         
  1824 
  1825         *fl = KROPart1;
  1825         *fl = KROPart1;
  1826         fl->Des().Append( *cid );
  1826         fl->Des().Append( *cid );
  1827         fl->Des().Append( KROPart2 );
  1827         fl->Des().Append( KROPart2 );
  1828             
  1828 
  1829         User::LeaveIfError( ProcessRightsObject( *fl, rightslist ) );
  1829         User::LeaveIfError( ProcessRightsObject( *fl, rightslist ) );
  1830     
  1830 
  1831         CleanupStack::PopAndDestroy(); // fl
  1831         CleanupStack::PopAndDestroy(); // fl
  1832 
  1832 
  1833         perm = rightslist[ 0 ];
  1833         perm = rightslist[ 0 ];
  1834         rightslist.Remove( 0 );
  1834         rightslist.Remove( 0 );
  1835         
  1835 
  1836         CleanupStack::PopAndDestroy(); // cleanup2
  1836         CleanupStack::PopAndDestroy(); // cleanup2
  1837         
  1837 
  1838         error = KErrNone;
  1838         error = KErrNone;
  1839         }
  1839         }
  1840         
  1840 
  1841     CleanupStack::PopAndDestroy(); // cid
  1841     CleanupStack::PopAndDestroy(); // cid
  1842 
  1842 
  1843     if ( !error )
  1843     if ( !error )
  1844         {
  1844         {
  1845         // There is something.
  1845         // There is something.
  1850         else
  1850         else
  1851             {
  1851             {
  1852             delete perm; perm = NULL;
  1852             delete perm; perm = NULL;
  1853             }
  1853             }
  1854         }
  1854         }
  1855         
  1855 
  1856     CleanupStack::PopAndDestroy(); // cleanup
  1856     CleanupStack::PopAndDestroy(); // cleanup
  1857     }
  1857     }
  1858 
  1858 
  1859 
  1859 
  1860 HBufC8* CDRMMessageParser::EncryptDCFFieldLC( const TDesC8& aOldHeader )
  1860 HBufC8* CDRMMessageParser::EncryptDCFFieldLC( const TDesC8& aOldHeader )
  1861     {
  1861     {
  1862     HBufC8* res = NULL;
  1862     HBufC8* res = NULL;
  1863     RDRMRightsClient client;
  1863     RDRMRightsClient client;
  1864     
  1864 
  1865     User::LeaveIfError( client.Connect() );
  1865     User::LeaveIfError( client.Connect() );
  1866     CleanupClosePushL( client );
  1866     CleanupClosePushL( client );
  1867 
  1867 
  1868     // Make sure FL rights exists.
  1868     // Make sure FL rights exists.
  1869     EnsureFLRightsExistL( client, NULL );
  1869     EnsureFLRightsExistL( client, NULL );
  1870 
  1870 
  1871     User::LeaveIfError( 
  1871     User::LeaveIfError(
  1872         client.EncodeRightsIssuerField( aOldHeader, res ) );
  1872         client.EncodeRightsIssuerField( aOldHeader, res ) );
  1873     
  1873 
  1874     CleanupStack::PopAndDestroy(); // client
  1874     CleanupStack::PopAndDestroy(); // client
  1875 
  1875 
  1876     CleanupStack::PushL( res );
  1876     CleanupStack::PushL( res );
  1877 
  1877 
  1878     return res;
  1878     return res;
  1879     }
  1879     }
  1880     
  1880 
  1881 // ========================== OTHER EXPORTED FUNCTIONS =========================
  1881 // ========================== OTHER EXPORTED FUNCTIONS =========================
  1882 
  1882 
  1883 //  End of File
  1883 //  End of File