diff -r 12af337248b1 -r bd7edf625bdd clock2/clockengines/clocktimezoneresolver/src/clockmcctzmapper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clock2/clockengines/clocktimezoneresolver/src/clockmcctzmapper.cpp Wed Sep 01 12:32:31 2010 +0100 @@ -0,0 +1,368 @@ +/* +* Copyright (c) 2008 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: The source file for the CClockMCCTzIdMapper class. +* +*/ + +// System includes +#include +#include +#include +#include + +// User includes +#include "clockmcctzmapper.h" +#include "clock_debug.h" + +// Constants + +// Literals +_LIT( KMCCResourceFileDir, "\\resource\\mcc\\" ); +_LIT( KMCCResourceFileName, "mcc.rsc" ); + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::NewL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockMCCTzIdMapper* CClockMCCTzIdMapper::NewL() + { + __PRINTS( "CClockMCCTzIdMapper::NewL - Entry" ); + + CClockMCCTzIdMapper* self = CClockMCCTzIdMapper::NewLC(); + CleanupStack::Pop( self ); + + __PRINTS( "CClockMCCTzIdMapper::NewL - Exit" ); + + return self; + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::NewLC +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockMCCTzIdMapper* CClockMCCTzIdMapper::NewLC() + { + __PRINTS( "CClockMCCTzIdMapper::NewLC - Entry" ); + + CClockMCCTzIdMapper* self = new ( ELeave ) CClockMCCTzIdMapper(); + CleanupStack::PushL( self ); + + self->ConstructL(); + + __PRINTS( "CClockMCCTzIdMapper::NewLC - Exit" ); + + return self; + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::ConstructL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockMCCTzIdMapper::ConstructL() + { + __PRINTS( "CClockMCCTzIdMapper::ConstructL - Entry" ); + + // Connect to the file server + User::LeaveIfError( iFs.Connect() ); + + // Get the full filename with drive letter + TFileName rscFileName; + TFindFile fileFinder( iFs ); + + // TFindFile applies search order that is from drive Y to A, then Z + TInt err = fileFinder.FindByDir( KMCCResourceFileName, KMCCResourceFileDir ); + + if ( err == KErrNone ) + { + // Found file. + rscFileName = fileFinder.File(); + } + else + { + __PRINTS( "Unable to open mcc.rsc. Leaving now!!" ); + + // Leave with reason, file not found. + User::Leave( KErrPathNotFound ); + } + + // Open the resource file. The resource file will not be localized as it + // only contains integers, so there is no need to find a language specific + // resource file name. + iMCCResourceFile.OpenL( iFs, rscFileName ); + iMCCResourceFile.ConfirmSignatureL(); + + // Assign buffer for holding resource + TInt resourceId = iMCCResourceFile.Offset() + EMCCFirstResource; + iResourceBuffer = iMCCResourceFile.AllocReadL( resourceId ); + + __PRINTS( "CClockMCCTzIdMapper::ConstructL - Exit" ); + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::~CClockMCCTzIdMapper +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockMCCTzIdMapper::~CClockMCCTzIdMapper() + { + __PRINTS( "CClockMCCTzIdMapper::~CClockMCCTzIdMapper - Entry" ); + + // Close the resource file. + iMCCResourceFile.Close(); + // Free up the resource buffer. + if( iResourceBuffer ) + { + delete iResourceBuffer; + iResourceBuffer = NULL; + } + + // Close the file server session. + iFs.Close(); + + __PRINTS( "CClockMCCTzIdMapper::~CClockMCCTzIdMapper - Exit" ); + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::UTCOffSetWithoutDSTChangesL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockMCCTzIdMapper::UTCOffSetWithoutDSTChangesL( RTz& aTz, const CTzId& aTzId ) const + { + TInt timeOffset( KErrNotFound ); + + TTime universalTime; + universalTime.UniversalTime(); + + // Get the current rules for the timezone rules + CTzRules* currentRules = aTz.GetTimeZoneRulesL( aTzId, universalTime, universalTime, ETzUtcTimeReference ); + if( currentRules ) + { + timeOffset = currentRules->InitialStdTimeOffset(); + delete currentRules; + } + + return timeOffset; + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::TzIdFromMccL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockMCCTzIdMapper::TzIdFromMccL( const RMobilePhone::TMobilePhoneNetworkCountryCode& aMCC, + RArray< CTzId >& aTzIdArray, + const TTimeIntervalMinutes& aStdTimeOffset ) + { + __PRINTS( "CClockMCCTzIdMapper::TzIdFromMccL - Entry" ); + + // Convert the TMobilePhoneNetworkCountryCode to a TInt. + TInt currentMcc; + TLex lexUtil( aMCC ); + User::LeaveIfError( lexUtil.Val( currentMcc ) ); + + __PRINT( "MCC: %d", currentMcc ); + + // Get all the DST zones that match mcc + DoGetTzIdFromMCCL( currentMcc, aTzIdArray ); + + // Limit the returned entries to those with a specific StdTimeOffset + TInt offset = aStdTimeOffset.Int(); + if( offset != -1 ) + { + // Connect to Tz + RTz tzHandle; + CleanupClosePushL( tzHandle ); + User::LeaveIfError( tzHandle.Connect() ); + + TInt currentZoneOffset; + TInt count = aTzIdArray.Count(); + // Loop through the array in reverse order, removing all entries + // with non matching standard time offsets. + for( TInt index( count - 1 ); index >= KErrNone; --index ) + { + currentZoneOffset = UTCOffSetWithoutDSTChangesL( tzHandle, aTzIdArray[ index ] ); + if( currentZoneOffset != offset ) + { + aTzIdArray.Remove( index ); + } + } + // Cleanup. + CleanupStack::PopAndDestroy( &tzHandle ); + } + + __PRINTS( "CClockMCCTzIdMapper::TzIdFromMccL - Exit" ); + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::TzIdFromOffsetL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockMCCTzIdMapper::TzIdFromOffsetL( const TTimeIntervalMinutes& aStdTimeOffset, RArray< CTzId >& aTzIdArray ) + { + __PRINTS( "CClockMCCTzIdMapper::TzIdFromOffsetL - Entry" ); + + // Reset the position in the resource buffer + iResourceReader.SetBuffer( iResourceBuffer ); + // First TInt is the number of array items + TInt numberOfItems( iResourceReader.ReadInt16() ); + + // Loop through the resource array reading the TzId + for( TInt index( KErrNone ); index < numberOfItems; ++index ) + { + TInt timeZoneId( iResourceReader.ReadInt16() ); + TInt mobileCC( iResourceReader.ReadInt16() ); + + CTzId* timeZone = CTzId::NewL( timeZoneId ); + CleanupStack::PushL( timeZone ); + + aTzIdArray.AppendL( *timeZone ); + + CleanupStack::PopAndDestroy( timeZone ); + timeZone = NULL; + } + + // Limit the returned entries to those with a specific StdTimeOffset + TInt timeOffset( aStdTimeOffset.Int() ); + + // Connect to Tz + RTz tzHandle; + CleanupClosePushL( tzHandle ); + User::LeaveIfError( tzHandle.Connect() ); + + TInt currentZoneOffset; + TInt idCount( aTzIdArray.Count() ); + + // Loop through the array in reverse order, removing all entries + // with non matching standard time offsets. + for( TInt index( idCount - 1 ); index >= KErrNone; --index ) + { + currentZoneOffset = UTCOffSetWithoutDSTChangesL( tzHandle, aTzIdArray[ index ] ); + if( currentZoneOffset != timeOffset ) + { + aTzIdArray.Remove( index ); + } + } + CleanupStack::PopAndDestroy( &tzHandle ); + + // This is a check to see if the timezone array has multiple entries with same timezone ID. + // This happens because many countries have multiple MCCs for a single timezone ID. + // For ex: India has MCCs 404 and 405 for the same timezone ID 1624 and offset GMT+5:30. + TInt zoneCount( aTzIdArray.Count() ); + if( 1 < zoneCount ) + { + CTzId& prevTzId = aTzIdArray[ KErrNone ]; + for( TInt zoneIndex( zoneCount - 1 ); zoneIndex > KErrNone; --zoneIndex ) + { + CTzId& curTzId = aTzIdArray[ zoneIndex ]; + if( prevTzId != curTzId ) + { + // There are multiple timezones. So skip. + break; + } + else + { + // Keep removing duplicate zone IDs. + aTzIdArray.Remove( zoneIndex ); + } + } + } + + __PRINTS( "CClockMCCTzIdMapper::TzIdFromOffsetL - Exit" ); + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::DoGetTzIdFromMCCL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockMCCTzIdMapper::DoGetTzIdFromMCCL( TInt aMcc, RArray< CTzId >& aTzIdArray ) + { + __PRINTS( "CClockMCCTzIdMapper::DoGetTzIdFromMCCL - Entry" ); + + __PRINT( "MCC:%d", aMcc ); + + // Reset the position in the resource buffer. + iResourceReader.SetBuffer( iResourceBuffer ); + // First TInt is the number of array items. + TInt numberOfItems( iResourceReader.ReadInt16() ); + + TInt timeZoneId; + TInt mobileCC; + CTzId* matchingDSTZone( NULL ); + + // Loop through the resource array reading the TzId / MCC pairs. + for( TInt index( KErrNone ); index < numberOfItems; ++index ) + { + timeZoneId = iResourceReader.ReadInt16(); + mobileCC = iResourceReader.ReadInt16(); + + // Found a match - create a new CTzId and append to the TzId array. + if( mobileCC == aMcc ) + { + matchingDSTZone = CTzId::NewL( timeZoneId ); + CleanupStack::PushL( matchingDSTZone ); + + aTzIdArray.AppendL( *matchingDSTZone ); + + CleanupStack::PopAndDestroy( matchingDSTZone ); + + matchingDSTZone = NULL; + } + } + + __PRINTS( "CClockMCCTzIdMapper::DoGetTzIdFromMCCL - Exit" ); + } + +// --------------------------------------------------------- +// CClockMCCTzIdMapper::MCCFromTzIdL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockMCCTzIdMapper::MCCFromTzIdL( const CTzId& aTzId ) + { + __PRINTS( "CClockMCCTzIdMapper::MCCFromTzIdL - Entry" ); + + // Reset the position in the resource buffer + iResourceReader.SetBuffer( iResourceBuffer ); + // First TInt is the number of array items + TInt numberOfItems( iResourceReader.ReadInt16() ); + TInt timeZoneId; + TInt mobileCC; + + // Loop through the resource array reading the TzId / MCC pairs + for( TInt index( KErrNone ); index < numberOfItems; ++index ) + { + timeZoneId = iResourceReader.ReadInt16(); + mobileCC = iResourceReader.ReadInt16(); + + // Found a match return the mcc + if( timeZoneId == aTzId.TimeZoneNumericID() ) + { + __PRINT( "Found a match, MCC - %d", mobileCC ); + + return mobileCC; + } + } + + __PRINTS( "CClockMCCTzIdMapper::MCCFromTzIdL - Exit" ); + + return KErrNotFound; + } + +// End of file