diff -r 000000000000 -r 2e3d3ce01487 tzservices/tzserver/Server/Source/tzsystemdata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tzservices/tzserver/Server/Source/tzsystemdata.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,426 @@ +// Copyright (c) 2008-2009 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: +// + +#include "tzsystemdata.h" +#include +#include +#include + +// Resource File locations +_LIT(KTzLocalizationTimeZoneResourceFileName,"\\Resource\\TimeZoneLocalization\\timezones.rSC"); +_LIT(KTzLocalizationGroupResourceFileName,"\\Resource\\TimeZoneLocalization\\timezonegroups.rSC"); +_LIT(KFlashPath,"c:\\Resource\\TimeZoneLocalization\\"); +_LIT(KFlashDrive, "c:"); +_LIT(KRom, "z:"); + +/** +Allocates and constructs a new CTzLocalizationResourceReader object +@return the newly constructed CTzLocalizationResourceReader +@internalTechnology +*/ +CTzSystemDataDb* CTzSystemDataDb::NewLC() + { + CTzSystemDataDb* self = new(ELeave) CTzSystemDataDb(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +/** +Destructor +@internalTechnology +*/ +CTzSystemDataDb::~CTzSystemDataDb() + { + iTimeZoneResourceFile.Close(); + if(iGroupResourceFileExists) + { + iGroupResourceFile.Close(); + } + delete iResourceBuffer; + iFs.Close(); + } + +/** +Second phase contructor +@internalTechnology +*/ +void CTzSystemDataDb::ConstructL() + { + User::LeaveIfError(iFs.Connect()); + + // If resource files are found on flash drive, + // these will be used exclusively otherwise the + // default ones on ROM will be used. + CDir* dirList; + // Get a list of files on flash drive + TInt ret = iFs.GetDir(KFlashPath, KEntryAttMaskSupported, ESortNone, dirList); + CleanupStack::PushL(dirList); + TFileName* timeZoneResourceFileName = new(ELeave) TFileName; + CleanupStack::PushL(timeZoneResourceFileName); + TFileName* groupResourceFileName = new(ELeave) TFileName; + CleanupStack::PushL(groupResourceFileName); + + TInt count = 0; + if(dirList != NULL) + { + count = dirList->Count(); + } + // Use the files on ROM + if(ret == KErrPathNotFound || count == 0) + { + timeZoneResourceFileName->Format(KRom); + timeZoneResourceFileName->Append(KTzLocalizationTimeZoneResourceFileName); + + groupResourceFileName->Format(KRom); + groupResourceFileName->Append(KTzLocalizationGroupResourceFileName); + } + // Use the files on system drive + else if(ret == KErrNone) + { + if(count > 0) + { + timeZoneResourceFileName->Format(KFlashDrive); + timeZoneResourceFileName->Append(KTzLocalizationTimeZoneResourceFileName); + + groupResourceFileName->Format(KFlashDrive); + groupResourceFileName->Append(KTzLocalizationGroupResourceFileName); + } + } + else + { + User::Leave(ret); + } + // Form the time zone resource filename using BaflUtils::NearestLanguageFile + BaflUtils::NearestLanguageFile(iFs,*timeZoneResourceFileName); + + // Form the time zone group resource filename using BaflUtils::NearestLanguageFile + BaflUtils::NearestLanguageFile(iFs,*groupResourceFileName); + + // Open resource files - this can be done now, as it is opened in EFileShareReadersOnly mode + iTimeZoneResourceFile.OpenL(iFs,*timeZoneResourceFileName); + iTimeZoneResourceFile.ConfirmSignatureL(); + + TRAPD(groupResErr,iGroupResourceFile.OpenL(iFs,*groupResourceFileName)); + + // Set iGroupResourceFileExists to so that it can be checked before + // iGroupResourceFile is used + iGroupResourceFileExists = (groupResErr == KErrNone); + if(iGroupResourceFileExists) + { + iGroupResourceFile.ConfirmSignatureL(); + iGroupResourceFileExists = ETrue; + } + CleanupStack::PopAndDestroy(3, dirList); // groupResourceFileName, timeZoneResourceFileName, dirList + } + +/** +Searches the time zone resource file for the given time zone ID. This function will +leave if the specified ID is not found. +@param aTimeZoneId time zone to search for. +@return The resource ID or KErrNotFound. +@internalTechnology +*/ +TInt CTzSystemDataDb::FindTimeZoneResourceIdL(TInt aTimeZoneId) + { + TInt initialOffset = FirstTimeZoneResourceIdL(); + + TInt idToCheck; + + // Search through all resources + TInt i = 0; + while(iTimeZoneResourceFile.OwnsResourceIdL(initialOffset + i)) + { + // Read current resource contents + BufferResourceL(iTimeZoneResourceFile,initialOffset + i); + + // get the first int16 (WORD in resource STRUCT) + idToCheck = iResourceReader.ReadInt16(); + + // get rid of the buffer, it's no longer needed + ResetResourceBuffer(); + + // perform check + if(idToCheck == aTimeZoneId) + { + // return the current resource ID + return initialOffset + i; + } + ++i; + } + + // If it's got to here the aId hasn't been found, so leave + User::Leave(KErrNotFound); + + return KErrNotFound; // To satisfy compiler + } + +/** +Returns the resource Id of the specified resource. This +leaves if this resource is not found in the resource file. +@param aResourceFile The resource file that the offset belongs to. +@param aOffset The offset to return. +@return The resource Id of the first resource containing localised data. +@internalTechnology +*/ +TInt CTzSystemDataDb::LocalizedResourceIdL(const RResourceFile& aResourceFile, const TTzResourceOffset aOffset) + { + TInt resourceIdToReturn = aResourceFile.Offset(); + + // Skip on the relevant number of resources, using the Offset enum + resourceIdToReturn += aOffset; + + if(!aResourceFile.OwnsResourceIdL(resourceIdToReturn)) + { + User::Leave(KErrNotFound); + } + + return resourceIdToReturn; + } + +/** +Returns the resource Id of the first time zone resource. This +leaves if this resource is not found in the resource file. +@return The resource Id of the first time zone resource. +@internalTechnology +*/ +TInt CTzSystemDataDb::FirstTimeZoneResourceIdL() + { + return LocalizedResourceIdL(iTimeZoneResourceFile,ETzFirstTimeZoneResource); + } + +/** +Returns the resource Id of the resource containing the default cached zone +information. This leaves if this resource is not found in the resource file. +@return The resource Id of the resource containing the default cached zone +information. +@internalTechnology +*/ +TInt CTzSystemDataDb::CachedTimeZoneResourceIdL() + { + return LocalizedResourceIdL(iTimeZoneResourceFile,ETzFirstLocalizedResource); + } + +/** +Fills iResourceBuffer with the resource specified by aResourceId and sets up +iResourceReader to read from this resource. This should always be followed by a +call to ResetResourceBuffer. This function will leave if the requested resource +is not found in the specified resource file. +@param aResourceFile The resourcefile to read from. +@param aResourceId The resource to read from. +@internalTechnology +*/ +void CTzSystemDataDb::BufferResourceL(const RResourceFile& aResourceFile, TInt aResourceId) + { + if(!aResourceFile.OwnsResourceIdL(aResourceId)) + { + User::Leave(KErrNotFound); + } + + // Assign buffer for holding resource + iResourceBuffer = aResourceFile.AllocReadL(aResourceId); + + // TResourceReader for getting data out of the buffer + iResourceReader.SetBuffer(iResourceBuffer); + } + +/** +Resets the iResourceBuffer that contains the binary data of a resource. +@internalTechnology +*/ +void CTzSystemDataDb::ResetResourceBuffer() + { + delete iResourceBuffer; + iResourceBuffer = NULL; + } + +CTzLocalizedTimeZoneRecord* CTzSystemDataDb::ReadTimeZoneL(TInt aTimeZoneId) + { + TInt resourceId = FindTimeZoneResourceIdL(aTimeZoneId); + return DoReadTimeZoneL(resourceId); + } + +/** +Reads in and returns a localized time zone found at the specified resource id. +@param aResourceId The resource ID of the time zone in the time zone resource +file +@return The localized time zone found at the specified resource ID. +@internalTechnology +*/ +CTzLocalizedTimeZoneRecord* CTzSystemDataDb::DoReadTimeZoneL(TInt aResourceId) + { + BufferResourceL(iTimeZoneResourceFile,aResourceId); + CTzLocalizedTimeZoneRecord* timeZone = CreateTimeZoneRecordFromResourceL(aResourceId); + ResetResourceBuffer(); + return timeZone; + } + +/** +This does the actual reading of a localized time zone from the resource file. +The iResourceReader MUST already have been set up with a call to +BufferResourceL(iTimeZoneResourceFile,...), BEFORE this function is called. + +@return A CTzLocalizedTimeZone containing the localized time zone information +that is currently found in iResourceReader. + +@internalTechnology +*/ +CTzLocalizedTimeZoneRecord* CTzSystemDataDb::CreateTimeZoneRecordFromResourceL(TInt aResourceId) + { + // Read localized time zone data form the resource file in the correct order + TInt16 timeZoneId = (TInt16)iResourceReader.ReadInt16(); + TPtrC standardName(iResourceReader.ReadTPtrC()); + TPtrC daylightName(iResourceReader.ReadTPtrC()); + TPtrC shortStandardName(iResourceReader.ReadTPtrC()); + TPtrC shortDaylightName(iResourceReader.ReadTPtrC()); + + CTzLocalizedTimeZoneRecord* timeZone = CTzLocalizedTimeZoneRecord::NewL(timeZoneId, standardName, + daylightName, shortStandardName, shortDaylightName, aResourceId); + + return timeZone; + } + +/** +From MTzLocalizationReader Read the cities that are in the specified time zone +into the specified city array. +@param aCities An array of cities that will contain the cities from the +specified time zone. +@param aTimeZoneId The ID of the time zone containing the cities to return,. +@leave KErrNotFound Leaves if the specified time zone is not found or it +contains no cities. +@internalTechnology +*/ +void CTzSystemDataDb::ReadCitiesL(RPointerArray& aCities, TInt aTimeZoneId) + { + TInt resourceId = FindTimeZoneResourceIdL(aTimeZoneId); + DoReadCitiesL(aCities, resourceId); + } + +/** +Reads in and adds the array of cities contained in the specified resource ID to +the supplied city array +@param The array of cities to which the the cities found in the time zone at +the specified resource ID will be appended to. +@param aResourceId The resource ID of the time zone that contains the cities to +be read. +@internalTechnology +*/ +void CTzSystemDataDb::DoReadCitiesL(RPointerArray& aCities, TInt aResourceId) + { + BufferResourceL(iTimeZoneResourceFile,aResourceId); + AddCityArrayFromResourceL(aCities,aResourceId); + ResetResourceBuffer(); + } + +/** +This does the actual reading of the localized cities from the resource file. +The iResourceReader MUST already have been set up with a call to +BufferResourceL(iTimeZoneResourceFile,...) BEFORE this function is called. +@param aCities The array of cities to add the resource cities to. +@param aResourceId The resource ID of the time zone containing the cities to +read. +@return An array of CTzLocalizedCity objects containing the cities that are +currently found in iResourceReader. +@internalTechnology +*/ +void CTzSystemDataDb::AddCityArrayFromResourceL(RPointerArray& aCities, TInt aResourceId) + { + // Eat up the localised time zone info from the resource + CTzLocalizedTimeZoneRecord* timeZone = CreateTimeZoneRecordFromResourceL(aResourceId); + TUint tzid = timeZone->Id(); + delete timeZone; + timeZone = NULL; + + // Get the number of cities (which automatically precedes the array as a WORD in the STRUCT) + TInt numCities = iResourceReader.ReadInt16(); + + // Leave if no cities are found + if(numCities < 1) + { + User::Leave(KErrNotFound); + } + + aCities.ReserveL(numCities + aCities.Count()); + // Loop through all the cities + for(TInt i = 0; i < numCities; ++i) + { + TUint8 groupId = iResourceReader.ReadUint8(); + TPtrC cityName; + cityName.Set(iResourceReader.ReadTPtrC()); + CTzLocalizedCityRecord* city = CTzLocalizedCityRecord::NewLC(cityName,groupId,i,tzid,aResourceId); + aCities.Append(city); + CleanupStack::Pop(city); + } + } + +CTzLocalizedCityRecord* CTzSystemDataDb::ReadDefaultCityL(TInt aTimeZoneId) + { + // Read the cities from the specified resource + RPointerArray cities; + CleanupStack::PushL(TCleanupItem(CTzLocalizedCityRecord::CleanupArray, &cities)); + ReadCitiesL(cities,aTimeZoneId); + + // Move first element (which is the default city) out of cities + // to stop it being deleted when cities is + CTzLocalizedCityRecord* defaultCity = cities[0]; + cities.Remove(0); + + CleanupStack::PopAndDestroy(); // cities + + return defaultCity; + } + +TInt CTzSystemDataDb::ReadFrequentlyUsedZoneIdL(TInt aFrequentlyUsedZone) + { + // You cannot pass ECachedTimeZones in as the argument, because it is only + // used to keep count of how many cached zones there are. + __ASSERT_ALWAYS(aFrequentlyUsedZone != CTzLocalizedTimeZone::ECachedTimeZones, User::Leave(KErrArgument)); + + TInt offset = CachedTimeZoneResourceIdL(); + + BufferResourceL(iTimeZoneResourceFile,offset); + + TInt tzid = 0; + TInt defaultHomeZoneId = iResourceReader.ReadInt16(); + TInt defaultInterestZoneId = iResourceReader.ReadInt16(); + TInt defaultRecentZone1Id = iResourceReader.ReadInt16(); + TInt defaultRecentZone2Id = iResourceReader.ReadInt16(); + switch(aFrequentlyUsedZone) + { + case CTzLocalizedTimeZone::EHomeZone: + tzid = defaultHomeZoneId; + break; + case CTzLocalizedTimeZone::EInterestZone: + tzid = defaultInterestZoneId; + break; + case CTzLocalizedTimeZone::ERecentZone1: + tzid = defaultRecentZone1Id; + break; + case CTzLocalizedTimeZone::ERecentZone2: + tzid = defaultRecentZone2Id; + break; + case CTzLocalizedTimeZone::ECurrentZone: // FALL THROUGH to default - current zone not supported + default: + User::Leave(KErrArgument); + } + ResetResourceBuffer(); + return tzid; + } + +CTzLocalizedTimeZoneRecord* CTzSystemDataDb::ReadFrequentlyUsedZoneL(TInt aFrequentlyUsedZone) + { + TInt tzid = ReadFrequentlyUsedZoneIdL(aFrequentlyUsedZone); + return ReadTimeZoneL(tzid); + }