dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpMetaHeader.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:37 +0100
branchRCL_3
changeset 48 13a33d82ad98
parent 0 822a42b6c3f1
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201029 Kit: 201035

/*
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:    Implementation of the Common Recording Engine RTP read class.*
*/




// INCLUDE FILES
#include <ipvideo/CRtpMetaHeader.h>
#include <bsp.h>
#include <etelmm.h>
#include "videoserviceutilsLogger.h"

// CONSTANTS
// None

// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CRtpMetaHeader::NewL
// Static two-phased constructor. Leaves object to cleanup stack.
// -----------------------------------------------------------------------------
//
CRtpMetaHeader* CRtpMetaHeader::NewL( RFile& aFile, const TMetaMode& aMode )
    {
    CRtpMetaHeader* self = CRtpMetaHeader::NewLC( aFile, aMode );
    CleanupStack::Pop( self );
    return self;
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::NewLC
// Static two-phased constructor. Leaves object to cleanup stack.
// -----------------------------------------------------------------------------
//
CRtpMetaHeader* CRtpMetaHeader::NewLC( RFile& aFile, const TMetaMode& aMode )
    {
    CRtpMetaHeader* self = new( ELeave ) CRtpMetaHeader( aFile, aMode );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::CRtpMetaHeader
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CRtpMetaHeader::CRtpMetaHeader( RFile& aFile, const TMetaMode& aMode )
  : iFile( aFile ),
    iMode( aMode ),
    iMetaData( NULL ),
    iDataPtr( 0, 0 ),
    iEsgDataPoint( KErrNotFound ),
    iSrtpDataPoint( KErrNotFound ),
    iSdpDataPoint( KErrNotFound ),
    iMetaTotal( KErrNotFound )
    {
    // None
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ConstructL()
    {
    LOG( "CRtpMetaHeader::ConstructL()" );
    
    // Mode
    if ( iMode == EMetaRead || iMode == EMetaUpdate )
        {
        // Read whole meta area
        ReadTintFromFileL( KMetaLengthPoint, iMetaTotal );

        // Meta header has reasonable length?
        if ( iMetaTotal > KMaxMetaHeaderLength || iMetaTotal <= 0 )
            {
            LOG( "CRtpMetaHeader::ConstructL(), Meta Total Corrupted" );
            User::Leave( KErrCorrupt );
            }

        // Room for header
        iMetaData = HBufC8::NewL( iMetaTotal );
        iDataPtr.Set( iMetaData->Des() );
        User::LeaveIfError( iFile.Read( KMetaLengthPoint, iDataPtr, iMetaTotal ) );
        
        // All data exist in meta header?
        if ( iDataPtr.Length() < iMetaTotal )
            {
            LOG( "CRtpMetaHeader::ConstructL(), Meta Header Corrupted" );
            User::Leave( KErrCorrupt );
            }

        // ESG data point ( device info point + device info data )
        iEsgDataPoint = KDeviceInfoPoint + KStringLengthBytes +
                        iDataPtr[KDeviceInfoPoint];
        
        // SRTP data point ( ESG data point + Service name + Program name )
        TInt snp( iEsgDataPoint + KStringLengthBytes + iDataPtr[iEsgDataPoint] );
        iSrtpDataPoint = snp + KStringLengthBytes + iDataPtr[snp];

        // SDD file point ( SRTP data point + SRTP data )
        const TInt srtplen( CRtpUtil::GetValueL( 
                            iDataPtr.Mid( iSrtpDataPoint, KIntegerBytes ) ) );
        User::LeaveIfError( srtplen );
        iSdpDataPoint = iSrtpDataPoint + KIntegerBytes + srtplen;
        }
    else // Write
        {
        iMetaData = HBufC8::NewL( 0 );
        // Room for meta length
        iMetaTotal = KMetaLengthPoint;
        AddIntegerL( KMetaLengthPoint, KErrNotFound );
        }
    }

// -----------------------------------------------------------------------------
// Destructor
//
CRtpMetaHeader::~CRtpMetaHeader()
// -----------------------------------------------------------------------------
    {
    LOG( "CRtpMetaHeader::~CRtpMetaHeader()" );
    
    delete iMetaData;
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::SeekHeaderPoint
// Getter for seek header point.
// Returns: Point to seek header
// -----------------------------------------------------------------------------
//
TInt CRtpMetaHeader::SeekHeaderPoint()
    {
    return iMetaTotal;
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::CommitL
// Writes meta header to the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::CommitL()
    {
    LOG( "CRtpMetaHeader::CommitL() in" );

    User::LeaveIfError( iMetaTotal );
    User::LeaveIfError( ( iMetaTotal > KMaxMetaHeaderLength ) * KErrCorrupt );
    
    if ( iMode == EMetaWrite )
        {
        User::LeaveIfError( iEsgDataPoint );
        User::LeaveIfError( iSrtpDataPoint );
        User::LeaveIfError( iSdpDataPoint );
        
        // Meta length
        iDataPtr.Delete( KMetaLengthPoint, KIntegerBytes );
        AddIntegerL( KMetaLengthPoint, iMetaTotal );
        
        User::LeaveIfError( iFile.Write( iDataPtr, iMetaTotal ) );
        }

    LOG( "CRtpMetaHeader::CommitL() out" );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteAttributesL
// Writes atributes to meta data header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteAttributesL( const SAttributes& aAtt )
    {
    TInt data( 0 );
    data|= aAtt.iOngoing << KOngoingFlagShift;
    data|= aAtt.iCompleted << KCompletedFlagShift;
    data|= aAtt.iProtected << KProtectedFlagShift;
    data|= aAtt.iFailed << KFailedFlagShift;
    data|= aAtt.iVersion << KVersionFieldShift;
    data|= aAtt.iQuality << KQualityFieldShift;
    data|= aAtt.iPostRule << KPostRuleFieldShift;
    data|= aAtt.iParental << KParentalFieldShift;

    AddIntegerL( KAttributesPoint, data );
    AddIntegerL( KPlayCountPoint, aAtt.iPlayCount );
    AddIntegerL( KPlaySpotPoint, aAtt.iPlaySpot );
    
    // Reserved room for 4 integers
    AddIntegerL( KReservedPoint1, 0 );
    AddIntegerL( KReservedPoint2, 0 );
    AddIntegerL( KReservedPoint3, 0 );
    AddIntegerL( KReservedPoint4, 0 );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteStartTimeL
// Writes start date/time info to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteStartTimeL( const TTime& aTime )
    {
    AddTimeL( KStartTimePoint, aTime );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteEndTimeL
// Writes end date/time info to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteEndTimeL( const TTime& aTime )
    {
    AddTimeL( KEndTimePoint, aTime );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteDurationL
// Writes duration of clip to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteDurationL( const TInt aDuration )
    {
    AddIntegerL( KDurationPoint, aDuration );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteSeekArrayPointL
// Writes seek array point of clip to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteSeekArrayPointL( const TInt aPoint )
    {
    AddIntegerL( KSeekArrayPoint, aPoint );
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteUserIdL
// Writes user id to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteUserIdL( const TDesC& aId )
    {
    WriteStringDataL( KUserIdPoint, aId );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteDeviceInfoL
// Writes device info to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteDeviceInfoL( const TDesC& aInfo )
    {
    WriteStringDataL( KDeviceInfoPoint, aInfo );
    iEsgDataPoint = KDeviceInfoPoint + KStringLengthBytes + aInfo.Length();
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteEsgDataL
// Writes ESG data to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteEsgDataL( const TDesC& aService, const TDesC& aProgram )
    {
    // Device info must exist first
    User::LeaveIfError( iEsgDataPoint );

    // Service name
    WriteStringDataL( iEsgDataPoint, aService );
    
    // Program name
    const TInt prog( iEsgDataPoint + KStringLengthBytes + aService.Length() );
    WriteStringDataL( prog, aProgram );
    iSrtpDataPoint = prog + KStringLengthBytes + aProgram.Length();
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteSrtpDataL
// Writes SRTP data to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteSrtpDataL( const TDesC8& aSrtpData )
    {
    // ESG data must exist first
    User::LeaveIfError( iSrtpDataPoint );
    User::LeaveIfError( ( iMode!=EMetaWrite ) * KErrAccessDenied );

    AddIntegerL( iSrtpDataPoint, aSrtpData.Length() );
    AddDataL( iSrtpDataPoint + KIntegerBytes, aSrtpData );
    iSdpDataPoint = iSrtpDataPoint + KIntegerBytes + aSrtpData.Length();
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteSdpDataL
// Writes SDP file data to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteSdpDataL( const TDesC8& aSdpData )
    {
    // SRTP data must exist first
    User::LeaveIfError( iSdpDataPoint );
    User::LeaveIfError( ( iMode != EMetaWrite ) * KErrAccessDenied );

    if ( aSdpData.Length() )
        {
        AddIntegerL( iSdpDataPoint, aSdpData.Length() );
        AddDataL( iSdpDataPoint + KIntegerBytes, aSdpData );
        }
    else
        {
        AddIntegerL( iSdpDataPoint, 0 );
        }
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadAttributesL
// Reads attributes of meta data header from clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadAttributesL( SAttributes& aAtt )
    {
    aAtt.iVersion = 0;

    // Attributes
    HBufC8* bytes = iDataPtr.Mid( KAttributesPoint, KIntegerBytes ).AllocLC();
    TUint data( CRtpUtil::GetValueL( bytes->Des() ) );
    CleanupStack::PopAndDestroy( bytes );
    aAtt.iOngoing = ( data >> KOngoingFlagShift ) & ETrue;
    aAtt.iCompleted = ( data >> KCompletedFlagShift ) & ETrue;
    aAtt.iProtected = ( data >> KProtectedFlagShift ) & ETrue;
    aAtt.iFailed = ( data >> KFailedFlagShift ) & ETrue;
    aAtt.iVersion = ( TUint8 )( ( data >> KVersionFieldShift ) & 0xF );
    aAtt.iQuality = ( TUint8 )( ( data >> KQualityFieldShift ) & KMaxTUint8 );
    aAtt.iPostRule = ( TUint8 )( ( data >> KPostRuleFieldShift ) & KMaxTUint8 );
    aAtt.iParental = ( TUint8 )( ( data >> KParentalFieldShift ) & KMaxTUint8 );

    // Play count
    bytes = iDataPtr.Mid( KPlayCountPoint, KIntegerBytes ).AllocLC();
    aAtt.iPlayCount = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    // Play start spot
    bytes = iDataPtr.Mid( KPlaySpotPoint, KIntegerBytes ).AllocLC();
    aAtt.iPlaySpot = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    // Reserved room for 4 integers
    /*
    bytes = iDataPtr.Mid( KReservedPoint1, KIntegerBytes ).AllocLC();
    aAtt.iReservedX = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    bytes = iDataPtr.Mid( KReservedPoint2, KIntegerBytes ).AllocLC();
    aAtt.iReservedX = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    bytes = iDataPtr.Mid( KReservedPoint3, KIntegerBytes ).AllocLC();
    aAtt.iReservedX = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    bytes = iDataPtr.Mid( KReservedPoint4, KIntegerBytes ).AllocLC();
    aAtt.iReservedX = CRtpUtil::GetValueL( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );
    */
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadStartTimeL
// Reads date/time of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadStartTimeL( TTime& aTime )
    {
    GetTimeL( KStartTimePoint, aTime );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadEndTimeL
// Reads date/time of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadEndTimeL( TTime& aTime )
    {
    GetTimeL( KEndTimePoint, aTime );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadDurationL
// Reads clip duration of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadDurationL( TInt& aDuration )
    {
    HBufC8* bytes = iDataPtr.Mid( KDurationPoint, KIntegerBytes ).AllocLC();
    aDuration = CRtpUtil::GetValueL( bytes->Des() );
    User::LeaveIfError( aDuration );
    CleanupStack::PopAndDestroy( bytes );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadSeekArrayPointL
// Reads seek array point of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadSeekArrayPointL( TInt& aPoint )
    {
    HBufC8* bytes = iDataPtr.Mid( KSeekArrayPoint, KIntegerBytes ).AllocLC();
    aPoint = CRtpUtil::GetValueL( bytes->Des() );
    User::LeaveIfError( aPoint );
    CleanupStack::PopAndDestroy( bytes );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadUserIdL
// Reads user id of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadUserIdL( TDes& aId )
    {
    ReadStringDataL( KUserIdPoint, aId );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadDeviceInfoL
// Reads device info of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadDeviceInfoL( TDes& aInfo )
    {
    ReadStringDataL( KDeviceInfoPoint, aInfo );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadEsgDataL
// Reads ESG data of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadEsgDataL( TDes& aService, TDes& aProgram )
    {
    User::LeaveIfError( iEsgDataPoint );

    // Service name
    ReadStringDataL( iEsgDataPoint, aService );
    
    // Program name
    const TInt prog( iEsgDataPoint + KStringLengthBytes + aService.Length() );
    ReadStringDataL( prog, aProgram );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadSrtpDataL
// Reads SRTP data of meta header from the clip.
// -----------------------------------------------------------------------------
//
HBufC8* CRtpMetaHeader::ReadSrtpDataL()
    {
    User::LeaveIfError( iSrtpDataPoint );

    // Length
    const TInt len( CRtpUtil::GetValueL( 
                    iDataPtr.Mid( iSrtpDataPoint, KIntegerBytes ) ) );
    // Data
    const TInt total( iSrtpDataPoint + KIntegerBytes + len );
    User::LeaveIfError( ( len < 0 || total > iDataPtr.MaxLength() ) * KErrCorrupt );
    HBufC8* buf = iDataPtr.Mid( iSrtpDataPoint + KIntegerBytes, len ).AllocL();
    return buf;
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadSdpDataL
// Reads SDP file data of meta header from the clip.
// -----------------------------------------------------------------------------
//
HBufC8* CRtpMetaHeader::ReadSdpDataL()
    {
    User::LeaveIfError( iSdpDataPoint );

    // Length
    const TInt len( CRtpUtil::GetValueL( 
                    iDataPtr.Mid( iSdpDataPoint, KIntegerBytes ) ) );
    // Data
    const TInt total( iSdpDataPoint + KIntegerBytes + len );
    User::LeaveIfError( ( len <= 0 || total > iDataPtr.MaxLength() ) * KErrCorrupt );
    HBufC8* buf = iDataPtr.Mid( iSdpDataPoint + KIntegerBytes, len ).AllocL();
    return buf;
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::WriteStringDataL
// Writes data with length info to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::WriteStringDataL( const TInt aPosition, const TDesC& aData )
    {
    const TInt len( aData.Length() );
    User::LeaveIfError( ( len > TInt( KMaxTUint8 ) ) * KErrArgument );
    User::LeaveIfError( ( iMode != EMetaWrite ) * KErrAccessDenied );
    
    // Length
    TBuf8<KStringLengthBytes> buf( KNullDesC8 );
    buf.Append( KCharSpace );
    buf[0] = ( TUint8 )( len );
    AddDataL( aPosition, buf );

    // Data to 8-bit
    HBufC8* data = HBufC8::NewLC( aData.Length() );
    TPtr8 ptr( data->Des() );
    ptr.Copy( aData );
    AddDataL( aPosition + KStringLengthBytes, ptr );
    CleanupStack::PopAndDestroy( data );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadStringDataL
// Reads data with length info of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadStringDataL( const TInt aPosition, TDes& aData )
    {
    User::LeaveIfError( ( aPosition < 0 || aPosition > iDataPtr.Length() )
                        * KErrArgument );
    const TInt len( iDataPtr[aPosition] );
    User::LeaveIfError( ( len < 0 || len > TInt( KMaxTUint8 ) ) * KErrCorrupt );
    User::LeaveIfError( ( len > aData.MaxLength() ) * KErrArgument );

    aData.Copy( iDataPtr.Mid( aPosition + KStringLengthBytes, len ) );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::AddTimeL
// Writes data/time or duration of clip to meta header of the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::AddTimeL( const TInt aPosition, const TTime& aTime )
    {
    HBufC8* bytes = CRtpUtil::MakeBytesLC( I64LOW( aTime.Int64() ) );
    AddDataL( aPosition, bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    bytes = CRtpUtil::MakeBytesLC( I64HIGH( aTime.Int64() ) );
    AddDataL( aPosition + KIntegerBytes, bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::GetTimeL
// Reads time value of meta header from the clip.
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::GetTimeL( const TInt aPosition, TTime& aTime )
    {
    TUint low( CRtpUtil::GetValueL(
        iDataPtr.Mid( aPosition, KIntegerBytes ) ) );
    TUint high( CRtpUtil::GetValueL( 
        iDataPtr.Mid( aPosition +  KIntegerBytes, KIntegerBytes ) ) );

    aTime = TInt64( MAKE_TINT64( high, low ) );
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::AddIntegerL
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::AddIntegerL( const TInt aPosition, const TInt aValue )
    {
    HBufC8* bytes = CRtpUtil::MakeBytesLC( aValue );
    AddDataL( aPosition, bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );
    }

// -----------------------------------------------------------------------------
// CRtpMetaHeader::AddDataL
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::AddDataL( const TInt aPosition, const TDesC8& aData )
    {
    // Write must be in certain order
    User::LeaveIfError( ( aPosition > iMetaTotal ) * KErrWrite );

    switch ( iMode )
        {
        case EMetaWrite:
            iMetaTotal = iMetaData->Length() + aData.Length();
            iMetaData = iMetaData->ReAllocL( iMetaTotal );
            iDataPtr.Set( iMetaData->Des() );
            iDataPtr.Insert( aPosition, aData );
            break;

        case EMetaUpdate:
            User::LeaveIfError( iFile.Write( aPosition, aData, aData.Length() ) );
            break;

        default:
            User::Leave( KErrNotSupported );
            break;
        }
    }
 
// -----------------------------------------------------------------------------
// CRtpMetaHeader::ReadTintFromFileL
// -----------------------------------------------------------------------------
//
void CRtpMetaHeader::ReadTintFromFileL( const TInt& aPosition, TInt& aValue )
    {
    HBufC8* bytes = HBufC8::NewLC( KIntegerBytes );
    TPtr8 ptr( bytes->Des() );
    User::LeaveIfError( iFile.Read( aPosition, ptr, KIntegerBytes ) );
    
    aValue = CRtpUtil::GetValueL( ptr );
    CleanupStack::PopAndDestroy( bytes );
    }
    
//  End of File