--- /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 <bautils.h>
+#include <tzlocalizedcityrecord.h>
+#include <tzlocalizedtimezonerecord.h>
+
+// 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<CTzLocalizedCityRecord>& 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<CTzLocalizedCityRecord>& 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<CTzLocalizedCityRecord>& 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<CTzLocalizedCityRecord> 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);
+ }