dvrengine/CommonRecordingEngine/DvrRtpClipHandler/src/CRtpFileBase.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:37 +0100
branchRCL_3
changeset 23 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 file base class.*
*/




// INCLUDE FILES
#include <ipvideo/CRtpFileBase.h>
#include "videoserviceutilsLogger.h"

// CONSTANTS
const TInt KFirstIntegerPoint( 0 );
const TInt KSecondIntegerPoint( KFirstIntegerPoint + KIntegerBytes );
const TInt KThirdIntegerPoint( KSecondIntegerPoint + KIntegerBytes );
const TInt KFourthIntegerPoint( KThirdIntegerPoint + KIntegerBytes );
const TInt KSeekArrayGranularity( 20 );

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

// -----------------------------------------------------------------------------
// CRtpFileBase::CRtpFileBase
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CRtpFileBase::CRtpFileBase()
  : CActive( CActive::EPriorityStandard ),
    iMode( EModeNone ),
    iThisGroup( KErrNotFound ),
    iGroupsTotalCount( KErrNotFound ),
    iFirstSeekAddr( KErrNotFound ),
    iLastSeekAddr( KErrNotFound ),
    iGroupTotalLen( KErrNotFound ),
    iNextGroupPoint( KErrNotFound ),
    iPrevGroupPoint( KErrNotFound ),
    iGroupTime( 0 ),
    iSeekHeaderPoint( KErrNotFound ),
    iDataPtr( 0, 0 )
    {
    CActiveScheduler::Add( this );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::ConstructL()
    {
    LOG( "CRtpFileBase::ConstructL()" );

    iSeekArray = new( ELeave ) CArrayFixFlat<SSeek>( KSeekArrayGranularity );
    }

// -----------------------------------------------------------------------------
// Destructor
//
// -----------------------------------------------------------------------------
//
CRtpFileBase::~CRtpFileBase()
    {
    LOG( "CRtpFileBase::~CRtpFileBase()" );
    // Do not call Cancel here, it will cause crashes (DoCancel of inherited
    // class is never called, instead it jumps to foobar address)
    iFile.Close();
    iFs.Close();
    delete iCurrentPath;
    delete iSeekArray;
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::DeleteTimeShiftFiles
// Deletes files used during time shift mode.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::DeleteTimeShiftFiles( RArray<STimeShiftSeek>& aShiftSeek )
    {
    LOG1( "CRtpFileBase::DeleteTimeShiftFiles(), count: %d", aShiftSeek.Count() );
    
    TInt index( KErrNotFound );
    const TInt count( aShiftSeek.Count() );
    for ( TInt i( 0 ); i < count; i++ )
        {
        if ( aShiftSeek[i].iNameIndex != index )
            {
            TPath clipPath( KDvrTimeShiftFile );
            index = aShiftSeek[i].iNameIndex;
            clipPath.AppendNum( index );
            iFs.Delete( clipPath );
            LOG1( "CRtpFileBase::DeleteTimeShiftFiles(), deleted: %S", &clipPath );
            }
        }

    aShiftSeek.Reset();
    }
    
// -----------------------------------------------------------------------------
// CRtpFileBase::WriteSeekHeaderL
// Writes seek header of all groups.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::WriteSeekHeaderL()
    {
    User::LeaveIfError( iSeekHeaderPoint );

    HBufC8* data = HBufC8::NewLC( KSeekHeaderBytes );
    TPtr8 ptr( data->Des() );
    
    HBufC8* bytes = CRtpUtil::MakeBytesLC( iGroupsTotalCount );
    ptr.Copy( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );
    
    bytes = CRtpUtil::MakeBytesLC( iFirstSeekAddr );
    ptr.Append( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    bytes = CRtpUtil::MakeBytesLC( iLastSeekAddr );
    ptr.Append( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    User::LeaveIfError( iFile.Write( iSeekHeaderPoint, ptr, KSeekHeaderBytes ) );
    CleanupStack::PopAndDestroy( data );
    }
 
// -----------------------------------------------------------------------------
// CRtpFileBase::ReadSeekHeaderL
// Readss seek header of all groups.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::ReadSeekHeaderL()
    {
    User::LeaveIfError( iSeekHeaderPoint );

    HBufC8* bytes = HBufC8::NewLC( KSeekHeaderBytes );
    TPtr8 ptr( bytes->Des() );
    User::LeaveIfError( iFile.Read( iSeekHeaderPoint, ptr, KSeekHeaderBytes ) );
    if ( ptr.Length() < KSeekHeaderBytes )
        {
        LOG( "CRtpFileBase::ReadSeekHeaderL(), Seek Header Corrupted" );
        User::Leave( KErrCorrupt );
        }

    iGroupsTotalCount = CRtpUtil::GetValueL( ptr.Mid( KFirstIntegerPoint,
                                                      KIntegerBytes ) );
    User::LeaveIfError( iGroupsTotalCount );
    iFirstSeekAddr = CRtpUtil::GetValueL( ptr.Mid( KSecondIntegerPoint,
                                                   KIntegerBytes ) );
    User::LeaveIfError( iFirstSeekAddr );
    iLastSeekAddr = CRtpUtil::GetValueL( ptr.Mid( KThirdIntegerPoint,
                                                  KIntegerBytes ) );
    User::LeaveIfError( iLastSeekAddr );
    CleanupStack::PopAndDestroy( bytes );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::ReadGroupHeaderL
// Reads group header.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::ReadGroupHeaderL()
    {
    User::LeaveIfError( iThisGroup );

    HBufC8* bytes = HBufC8::NewLC( KGroupHeaderBytes );
    TPtr8 ptr( bytes->Des() );

    User::LeaveIfError( iFile.Read( iThisGroup, ptr, KGroupHeaderBytes ) );
    UpdateGroupHeaderVariablesL( ptr );

    CleanupStack::PopAndDestroy( bytes );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::UpdateGroupHeaderVariablesL
// Updates group header variables from readed data.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::UpdateGroupHeaderVariablesL( const TDesC8& aDataPtr )
    {
    if ( aDataPtr.Length() < KGroupHeaderBytes )
        {
        LOG( "CRtpFileBase::UpdateGroupHeaderVariablesL(), Group Header Corrupted" );
        User::Leave( KErrCorrupt );
        }

    iGroupTotalLen  = CRtpUtil::GetValueL( aDataPtr.Mid( KFirstIntegerPoint ,
                                                         KIntegerBytes ) );
    User::LeaveIfError( iGroupTotalLen );
    iNextGroupPoint = CRtpUtil::GetValueL( aDataPtr.Mid( KSecondIntegerPoint,
                                                         KIntegerBytes ) );
    User::LeaveIfError( iNextGroupPoint );
    iPrevGroupPoint = CRtpUtil::GetValueL( aDataPtr.Mid( KThirdIntegerPoint,
                                                         KIntegerBytes ) );
    User::LeaveIfError( iPrevGroupPoint );
    iGroupTime = CRtpUtil::GetValueL( aDataPtr.Mid( KFourthIntegerPoint,
                                                    KIntegerBytes ) );
    User::LeaveIfError( iGroupTime );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::AppendSeekArrayL
// Appends one item to seek array.
// -----------------------------------------------------------------------------
//
void CRtpFileBase::AppendSeekArrayL( const TUint aTime, const TInt aPoint )
    {
#ifdef CR_ALL_LOGS
    LOG2( "CRtpFileBase::AppendSeekArrayL(), aTime: %u, aPoint: %d", 
                                             aTime, aPoint );
#endif // CR_ALL_LOGS

    SSeek seek;
    seek.iTime = aTime;
    seek.iPoint = aPoint;
    iSeekArray->AppendL( seek );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::SaveSeekArrayL
//
// -----------------------------------------------------------------------------
//
void CRtpFileBase::SaveSeekArrayL()
    {
    LOG1( "CRtpFileBase::SaveSeekArrayL(), count: %d", iSeekArray->Count() );
    
    const TInt len( KIntegerBytes + iSeekArray->Count() * 2 * KIntegerBytes );
    HBufC8* data = HBufC8::NewLC( len );
    TPtr8 ptr( data->Des() );
    
    // Total count
    HBufC8* bytes = CRtpUtil::MakeBytesLC( iSeekArray->Count() );
    ptr.Copy( bytes->Des() );
    CleanupStack::PopAndDestroy( bytes );

    for ( TInt i( 0 ); i < iSeekArray->Count(); i++ )
        {
        // Time
        bytes = CRtpUtil::MakeBytesLC( iSeekArray->At( i ).iTime );
        ptr.Append( bytes->Des() );
        CleanupStack::PopAndDestroy( bytes );

        // Point
        bytes = CRtpUtil::MakeBytesLC( iSeekArray->At( i ).iPoint );
        ptr.Append( bytes->Des() );
        CleanupStack::PopAndDestroy( bytes );

#ifdef CR_ALL_LOGS
        LOG3( "CRtpFileBase::SaveSeekArrayL(), ind: %d, time: %u, point: %d",
               i, iSeekArray->At( i ).iTime, iSeekArray->At( i ).iPoint );
#endif // CR_ALL_LOGS
        }

    User::LeaveIfError( iFile.Write( iNextGroupPoint, ptr, len ) );
    CleanupStack::PopAndDestroy( data );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::ReadSeekArrayL
//
// -----------------------------------------------------------------------------
//
TBool CRtpFileBase::ReadSeekArrayL( const TInt aPoint )
    {
    User::LeaveIfError( aPoint );
    HBufC8* bytes = HBufC8::NewLC( KIntegerBytes );
    TPtr8 ptr( bytes->Des() );
    
    // Verify read point
    TInt size( KErrNotFound );
    iFile.Size( size );
    User::LeaveIfError( ( aPoint > ( size - KIntegerBytes ) ) * KErrCorrupt );
    
    // Total count
    User::LeaveIfError( iFile.Read( aPoint, ptr, KIntegerBytes ) );
    const TInt count( CRtpUtil::GetValueL( ptr ) );
    CleanupStack::PopAndDestroy( bytes );
    LOG1( "CRtpFileBase::ReadSeekArrayL(), count: %d", count );
    
    // Any point stored?
    if ( count > 0 )
        {
        // Read array from clip
        User::LeaveIfError( ( count > ( KMaxTInt / 2 / KIntegerBytes ) ) * KErrCorrupt );
        const TInt len( count * 2 * KIntegerBytes );
        HBufC8* data = HBufC8::NewLC( len );
        ptr.Set( data->Des() );
        User::LeaveIfError( iFile.Read( aPoint + KIntegerBytes, ptr, len ) );
    
        // Set seek array
        for ( TInt i( 0 ); i < count; i++ )
            {
            const TInt next( i * 2 * KIntegerBytes );
            if ( ptr.Length() < ( next + ( 2 * KIntegerBytes ) ) )
                {
                LOG( "CRtpFileBase::ReadSeekArrayL(), Seek Array Corrupted" );
                User::Leave( KErrCorrupt );
                }

            // Time
            TUint time( CRtpUtil::GetValueL( ptr.Mid( next, KIntegerBytes ) ) );
            // Point
            TInt point( CRtpUtil::GetValueL( ptr.Mid( next + KIntegerBytes,
                                                      KIntegerBytes ) ) );
            User::LeaveIfError( point );
            AppendSeekArrayL( time, point );
#ifdef CR_ALL_LOGS
            LOG3( "CRtpFileBase::ReadSeekArrayL(), ind: %d, time: %u, point: %d",
                                                   i, time, point );
#endif // CR_ALL_LOGS
            }
    
        CleanupStack::PopAndDestroy( data );
        }

    return ( count > 0 );
    }

// -----------------------------------------------------------------------------
// CRtpFileBase::LogVariables
// -----------------------------------------------------------------------------
//
void CRtpFileBase::LogVariables( const TDesC& aMethod )
    {
#ifdef CR_ALL_LOGS
    LOG1( "CRtpFileBase::LogVariables(), Method: %S", &aMethod );
    LOG1( "CRtpFileBase::LogVariables(), iMode : %d", iMode );
    LOG1( "CRtpFileBase::LogVariables(), GTC   : %d", iGroupsTotalCount );
    LOG1( "CRtpFileBase::LogVariables(), FSA   : %d", iFirstSeekAddr );
    LOG1( "CRtpFileBase::LogVariables(), LSA   : %d", iLastSeekAddr );
    LOG1( "CRtpFileBase::LogVariables(), This  : %d", iThisGroup );
    LOG1( "CRtpFileBase::LogVariables(), GTL   : %d", iGroupTotalLen );
    LOG1( "CRtpFileBase::LogVariables(), NGP   : %d", iNextGroupPoint );
    LOG1( "CRtpFileBase::LogVariables(), PGP   : %d", iPrevGroupPoint );
    LOG1( "CRtpFileBase::LogVariables(), GTime : %u", iGroupTime );
#else // CR_ALL_LOGS
    ( void )aMethod;
#endif // CR_ALL_LOGS
    }

// End of File