srsf/sisrscontrollerplugin/src/asrplugindataloader.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:29:17 +0100
branchRCL_3
changeset 19 e36f3802f733
parent 0 bf1d17376201
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "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:  Language package data file loader 
*
*/


// INCLUDE FILES
#include "asrplugindataloader.h"
#include "sysconfigprovider.h"


#ifdef __SIND_AUTOCONF_LID
#include <syslangutil.h>
/* MSysConfigProvider is a wrapper for get syslangutil. This makes it easier to test without */
/* dependency to the actual language configuration in the emulator environment. The test  */
/* class implements this interface. */
class TDefaultConfig : public MSysConfigProvider {
public:
	TDefaultConfig() {};
	~TDefaultConfig() {};
	TInt GetInstalledLanguages( CArrayFixFlat<TInt>*& aLanguages, RFs* aFileServerSession = NULL ) 
	{
		return SysLangUtil::GetInstalledLanguages(aLanguages, aFileServerSession);		
	};
};
#endif  // __SIND_AUTOCONF_LID

// Local constants

_LIT( KZDriveLetter, "z" ); 
 

#ifdef __SIND_AUTOCONF_LID
const TUint32 KTtpAutoConfLidPackageType = 1;
const TUint32 KTtpAutoConfLidPackageID   = 1;
const TInt KLidBufGranularity = 1000;
#endif  // __SIND_AUTOCONF_LID


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

// -----------------------------------------------------------------------------
// CDataLoaderLoader::CDataLoader
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CDataLoader::CDataLoader() 
    {
    // Nothing
    }

// -----------------------------------------------------------------------------
// CDataLoader::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CDataLoader::ConstructL( const TDesC& aPrefixOfFileName,
							  const TDesC& aSeparator,                                     
                              const TDesC& aPostfixOfFileName,
                              MSysConfigProvider *aProvider )
    {
    iPrefixOfFileName = HBufC::NewL( aPrefixOfFileName.Length() );
    (*iPrefixOfFileName) = aPrefixOfFileName;
    iSeparator = HBufC::NewL( aSeparator.Length() );
    (*iSeparator) = aSeparator;
    iPostfixOfFileName = HBufC::NewL( aPostfixOfFileName.Length() );
    (*iPostfixOfFileName) = aPostfixOfFileName;
    
	iProvider = aProvider;

    // Open file session
    User::LeaveIfError( iFs.Connect() );
    }

// -----------------------------------------------------------------------------
// CDataLoader::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CDataLoader* CDataLoader::NewL( const TDesC& aPrefixOfFileName,
								const TDesC& aSeparator,                                     
                                const TDesC& aPostfixOfFileName,
                                MSysConfigProvider *aProvider )
    {
    CDataLoader* self = new ( ELeave ) CDataLoader();
    
    CleanupStack::PushL( self );
    self->ConstructL( aPrefixOfFileName,
					  aSeparator,                                     
                      aPostfixOfFileName,
                      aProvider);
    CleanupStack::Pop( self );
    
    return self;
    }

// -----------------------------------------------------------------------------
// CDataLoader::~CDataLoader
// Destructor.
// -----------------------------------------------------------------------------
//
CDataLoader::~CDataLoader()
    {
    delete iPrefixOfFileName,
	delete iSeparator,                                     
    delete iPostfixOfFileName;    
    
    iFs.Close();
    }

// -----------------------------------------------------------------------------
// CDataLoader::PackageName
// Construct filename for requested package
// -----------------------------------------------------------------------------
//	
void CDataLoader::PackageName (TFileName &aFileName, TUint32 aPackageType, TUint32 aPackageID) 
{
	// Resolve the name of the file
	// filename is <iPrefixOfFileName>_<PackageType>_<aPackageID><iPostfixOfFileName>

	aFileName.Copy( iPrefixOfFileName->Des() );          //  path/SRSF_
	aFileName.AppendNumUC( aPackageType );               //  path/SRSF_1
	aFileName.Append( iSeparator->Des() );               //  path/SRSF_1_
	aFileName.AppendNumUC( aPackageID );                 //  path/SRSF_1_326
	aFileName.Append( iPostfixOfFileName->Des() );       //  path/SRSF_1_326.bin
}

#ifdef __SIND_AUTOCONF_LID
// -----------------------------------------------------------------------------
// CDataLoader::AppendLoadL
// Load language package file to the end of buffer
// -----------------------------------------------------------------------------
//	
void CDataLoader::AppendLoadL( CBufBase *aBuffer,
								TUint32 aPackageType, 
								TUint32 aPackageID ) 
{
	// Resolve filename
	TFileName fileName;
	PackageName (fileName, aPackageType, aPackageID);

	// Load data
	HBufC8* buffer = NULL;
	
	TRAPD( err, buffer = DoLoadL( fileName, 0, KMaxTUint32 ));  // IMPLICIT: LID packages are loaded completely
 	if( err == KErrNone && buffer ) 
 	{
		CleanupStack::PushL( buffer );                    // ResizeL may leave below

		TInt prevSize = aBuffer->Size();                  // size before resize
		TInt newSize  = aBuffer->Size() + buffer->Size(); // new size for lid data buffer

		aBuffer->ResizeL( newSize );                      // resize lid data buffer
		aBuffer->Write( prevSize, *buffer );              // append data from read buffer

		CleanupStack::PopAndDestroy(buffer);              // buffer copied -> free
	}
}



// -----------------------------------------------------------------------------
// CDataLoader::LoadSysLangPackagesL
// Load LID language data to a buffer according to installed system languages
// -----------------------------------------------------------------------------
//	
void CDataLoader::SysLangPackagesToBufferL( CBufBase *aBuffer ) 
{        
	MSysConfigProvider *config = iProvider;
	TDefaultConfig defaultProvider;
	if (!config) config = &defaultProvider;

	// Get installed languages
	CArrayFixFlat<TInt>* languages( NULL );

	//User::LeaveIfError (SysLangUtil::GetInstalledLanguages(languages, &iFs));
	User::LeaveIfError (config->GetInstalledLanguages(languages, &iFs));
	CleanupStack::PushL( languages ) ;

	// Loop over installed languages
	for ( TInt i = 0 ; i < languages->Count(); i++ )
	{
		AppendLoadL(aBuffer, KTtpAutoConfLidPackageType, languages->At(i));
	}// next language
	
	CleanupStack::PopAndDestroy( languages );
}

// -----------------------------------------------------------------------------
// CDataLoader::ConstructLidDataL
// Load LID language data to a buffer according to installed system languages
// -----------------------------------------------------------------------------
//	
HBufC8* CDataLoader::ConstructLidDataL()
{
	CBufBase* lidDataBuffer = CBufSeg::NewL( KLidBufGranularity ) ; // accumulates the binary data from lid model files
	CleanupStack::PushL( lidDataBuffer ) ;

	SysLangPackagesToBufferL (lidDataBuffer);

	// Prepare returnable data
	HBufC8* dataBuffer = NULL;
	
	if( lidDataBuffer->Size() > 0 ) 
	{
		// If any data was loaded, create a buffer for it
		dataBuffer = HBufC8::NewL( lidDataBuffer->Size() );     // create a returnable buffer
		TPtr8 dataBufferPtr = dataBuffer->Des();                        // get a modifiable pointer to it
		lidDataBuffer->Read( 0, dataBufferPtr, lidDataBuffer->Size() ); // put the lid data into it
	}

	CleanupStack::PopAndDestroy( lidDataBuffer ) ;  

	return dataBuffer;
}
#endif  // __SIND_AUTOCONF_LID


// -----------------------------------------------------------------------------
// CDataLoader::LoadData
// Load language package file. It resolves the name of the language package
// -----------------------------------------------------------------------------
//	
HBufC8* CDataLoader::LoadData( TUint32 aPackageType, 
								TUint32 aPackageID,
								TUint32 aStartPosition,
								TUint32 aEndPosition ) {

	TInt err;
	HBufC8* buffer = NULL;

#ifdef __SIND_AUTOCONF_LID
	// If LID data is requested, construct it from installed LID binary files
	// Otherwise run normal data loading

	if( aPackageType == KTtpAutoConfLidPackageType &&
		aPackageID   == KTtpAutoConfLidPackageID )
	{
		TRAP( err, buffer = ConstructLidDataL() );
	}
#endif  // __SIND_AUTOCONF_LID

	if (!buffer)	{
		TFileName fileName;
		PackageName (fileName, aPackageType, aPackageID);
	
		// Load data    
		TRAP( err, buffer = DoLoadL( fileName, aStartPosition, aEndPosition ) );
	}

	if ( err == KErrNone )
	{
		return buffer;
  }
	else
	{
		return NULL;
	}    
}
                                         


// -----------------------------------------------------------------------------
// CDataLoader::DoLoadL
// Actual file loading function
// -----------------------------------------------------------------------------
//	
HBufC8* CDataLoader::DoLoadL( TFileName& aFileName,
                              TUint32 aStartPosition, 
                              TUint32 aEndPosition )
    {
    TInt fileSize( 0 );
    RFile dataFile;
    TInt readLength;

    // Open file	
    TInt err = dataFile.Open( iFs, aFileName, EFileRead);
	 
		if ( err != KErrNone )	 
		{		
			aFileName.Replace(0,1,KZDriveLetter); // "z:\"
			TInt err = dataFile.Open( iFs, aFileName, EFileRead);		 
			if ( err != KErrNone )
          {
    			return NULL;
          }
		}

	CleanupClosePushL( dataFile );
    // Try to resolve how much should be read
    readLength = aEndPosition - aStartPosition;
    User::LeaveIfError( dataFile.Size( fileSize ) );

    if ( aEndPosition != KMaxTUint32 )
        {
        // Cannot read more than filesize
        if ( ( readLength > fileSize ) || ( readLength < 0 ) )
            {
            readLength = fileSize;
            }
        }
    else
        {
        readLength = fileSize;
        }
    
    // Seek the starting point
    // Casting needed to convert from uint to int which is needed by Seek()
    TInt startPosition = ( TInt ) aStartPosition;
    dataFile.Seek( ESeekStart, startPosition );

    // Reserve enough memory for the data
    HBufC8* fileBuffer = HBufC8::NewLC( readLength );
    TPtr8 bufferPtr( fileBuffer->Des() );
    
    User::LeaveIfError( dataFile.Read( bufferPtr ) );

    CleanupStack::Pop( fileBuffer );
    CleanupStack::PopAndDestroy( &dataFile );
    return fileBuffer;
    }

// End of File