diff -r 000000000000 -r 2e3d3ce01487 tzpcside/tzcompiler/Source/TzTables.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tzpcside/tzcompiler/Source/TzTables.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,575 @@ +// Copyright (c) 2004-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: +// DST TZ Database Compiler +// +// + +#include "TzGlobals.h" +#include "TzTables.h" +#include "TZNode.h" +#include "TZDocument.h" +#include "TzHelpers.h" +#include // sort +#include +#include +#include +using namespace std; +//============================================================================ +// CTzCpLinksTable::CTzCpLinksTable +//============================================================================ +CTzCpLinksTable::CTzCpLinksTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpLinksTable::AssembleL +// Adds a link node to the link table. At this stage a CTzCpLink consists of +// two CTzCpString pointers. One is to the string for the link, the other is +// the name of the linked zone. The actual zone to be linked will be resolved +// during the linker stage of the compilation process. When the link table is +// externalised the persisted class (TTzLink) will be populated with the +// offsets to the string and linkedzone objects in the database +//============================================================================ +CTzCpLink& CTzCpLinksTable::AssembleL(CTZNode& aNode) + { + CTzCpLink* aNewLink = new CTzCpLink(iDocument); + aNewLink->AssembleL(aNode); + iVector.push_back(aNewLink); + return *aNewLink; + } +//============================================================================ +// CTzCpLinksTable::ExternaliseL +// Write the links table to a file +//============================================================================ +void CTzCpLinksTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToLinksTable = aFilestream.tellp(); + // write out the number of links + TUint16 numLinks = iVector.size(); + aFilestream.write((char*)&numLinks,sizeof(numLinks)); + + for (int x = 0; x < numLinks;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } + +//============================================================================ +// CTzCpLinksTable::FindZone +// Given a link name, returns the "real" database zone it links to +// (allowing for "cascade linking": link_1 -> link_2 -> ... -> link_n -> Zone) +//============================================================================ +CTzCpZone* CTzCpLinksTable::FindZone(std::string& aLinkName) + { + CTzCpZone* zone = NULL; + std::string name = aLinkName; + + // iterate through the collection of links + std::vector::iterator iter = iVector.begin(); + CTzCpLink** lastElementPtr = iVector.end(); + while(iter != lastElementPtr) + { + if ((*iter)->iLinkString->iString == name) + { + // name appears as the "old name" in one of the links + // recursively search for the new name + name = (*iter)->iRegionString->iString; + if (name.length() > 0) + {// new names are not guaranteed to be in the form Region/Zone + name += '/'; + } + name += (*iter)->iZoneString->iString; + return FindZone(name); + } + iter++; + } + + // aLinkName was not found as the old name in any of the links + // this means that aLinkName is not a link but the name of a real zone + return iDocument.ZonesTable()->GetZone(name); + } + +//============================================================================ +// CTzCpRuleSetsTable::CTzCpRuleSetsTable +//============================================================================ +CTzCpRuleSetsTable::CTzCpRuleSetsTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpRuleSetsTable::AssembleL +//============================================================================ +CTzCpRuleSet& CTzCpRuleSetsTable::AssembleL(CTZNode& aNode) + { + //Get the current Ruleset name + string currentRuleSetName = aNode.NodeList()[ERuleFormatName]->iValue; + return *GetRuleSet(currentRuleSetName); + } +//============================================================================ +// CTzCpRuleSetsTable::ExternaliseL +// Write the rule set table to file +//============================================================================ +void CTzCpRuleSetsTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToRuleSetsTable = aFilestream.tellp(); + //Write the number of rulesets + TUint16 numRuleSets = iVector.size(); + aFilestream.write((char*)&numRuleSets,sizeof(numRuleSets)); + + TUint16 ruleUseOffset = 0; + for (int x = 0; x < numRuleSets;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } +//============================================================================ +// CTzCpRuleSetsTable::GetRuleSet +// Searches for a match with aRuleSetName in the iStrings vector. If a match +// is found the ruleset pointer from the iRuleSets vector with the matching +// index is returned. If no match is found, a new ruleset is created and +// added to the rulesets, the name is added to the strings and a pointer to +// the new ruleset is returned. +//============================================================================ +CTzCpRuleSet* CTzCpRuleSetsTable::GetRuleSet(string aRuleSetName) + { + int numRuleSets = iVector.size(); + for (int index = 0; index < numRuleSets; index++) + { + if (iVector[index]->Name() == aRuleSetName) + { + return iVector[index]; + } + } + //New RuleSet required + CTzCpRuleSet* newRuleSet = new CTzCpRuleSet(iDocument,aRuleSetName); + iVector.push_back(newRuleSet); + return newRuleSet; + } +//============================================================================ +// CTzCpRuleSetsTable::GetRuleSetIndex +// Gets the index of the ruleset from the ruleset name +//============================================================================ +int CTzCpRuleSetsTable::GetRuleSetIndex(std::string aRuleSetName) + { + int size = iVector.size(); + for (int index = 0; index < size; index++) + { + if (iVector[index]->Name() == aRuleSetName) + { + return index; + } + } + GetRuleSet(aRuleSetName); + return GetRuleSetIndex(aRuleSetName); + } + +//============================================================================ +// CTzCpRuleSetsTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpRuleSetsTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } + +//============================================================================ +// CTzCpRuleDefinitionsTable::CTzCpRuleDefinitionsTable +//============================================================================ +CTzCpRuleDefinitionsTable::CTzCpRuleDefinitionsTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpRuleDefinitionsTable::AddRuleDefinition +// Adds a CTzCpRuleDefinition to the collection of rule definitions +// iRuleDefinitions takes ownership of aRuleDefinition. Checks that the +// Rule definition does not already exist before adding it. If it does exist, +// a reference to the duplicate is returned. If it does not exist then it is +// added and the new reference is returned. +//============================================================================ +CTzCpRuleDefinition& CTzCpRuleDefinitionsTable::AddRuleDefinition(CTzCpRuleDefinition* aRuleDefinition) + { + //Checks for a match - quick and dirty - consider revising + int size = iVector.size(); + for (int x = 0; x < size; x++) + { + TTzRuleDefinition tmpRuleDef = iVector[x]->iPersistedEntity; + if ((tmpRuleDef.iStdTimeOffset == aRuleDefinition->iPersistedEntity.iStdTimeOffset) && + (tmpRuleDef.iMonth == aRuleDefinition->iPersistedEntity.iMonth) && + (tmpRuleDef.iDayRule == aRuleDefinition->iPersistedEntity.iDayRule) && + (tmpRuleDef.iDayOfMonth == aRuleDefinition->iPersistedEntity.iDayOfMonth) && + (tmpRuleDef.iDayOfWeek == aRuleDefinition->iPersistedEntity.iStdTimeOffset) && + (tmpRuleDef.iTimeReference == aRuleDefinition->iPersistedEntity.iTimeReference) && + (tmpRuleDef.iTimeOfChange == aRuleDefinition->iPersistedEntity.iTimeOfChange)) + { + + //If we don't add the ruledefinition to the vector we + //are responsible for deleting it, as clients will + //assume they have passed ownership to the table. + delete aRuleDefinition; + return *iVector[x]; + } + } + iVector.push_back(aRuleDefinition); + return *iVector[iVector.size() -1]; + } +//============================================================================ +// CTzCpRuleDefinitionsTable::AssembleL +//============================================================================ +CTzCpRuleDefinition& CTzCpRuleDefinitionsTable::AssembleL(CTZNode& aNode) + { + CTzCpRuleDefinition* aRuleDefinition = new CTzCpRuleDefinition(iDocument); + aRuleDefinition->AssembleL(aNode); + return AddRuleDefinition(aRuleDefinition); + } +//============================================================================ +// CTzCpRuleDefinitionsTable::ExternaliseL +// Write the rule definition table to file +//============================================================================ +void CTzCpRuleDefinitionsTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToRuleDefinitionsTable = aFilestream.tellp(); + //Write number of rule definitions + TUint16 numRuleDefs = iVector.size(); + aFilestream.write((char*)&numRuleDefs,sizeof(numRuleDefs)); + + for (int x = 0; x < numRuleDefs;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } + +//============================================================================ +// CTzCpRuleDefinitionsTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpRuleDefinitionsTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } + +//============================================================================ +// CTzCpStringTable::CTzCpStringTable +//============================================================================ +CTzCpStringTable::CTzCpStringTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } + +//============================================================================ +// CTzCpStringTable::ExternaliseL +// Write the string table to file +//============================================================================ +void CTzCpStringTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToStringTable = aFilestream.tellp(); + //Write number of strings + TUint16 numStrings = iVector.size(); + aFilestream.write((char*)&numStrings,sizeof(numStrings)); + + for (int x = 0; x < numStrings;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } +//============================================================================ +// CTzCpStringTable::AddString +// Returns a reference to the added string, or if the string already exists +// a reference to the existing string +//============================================================================ +CTzCpString& CTzCpStringTable::AddString(std::string aString) + { + int size = iVector.size(); + for (int i = 0; i < size; i++) + { + if (aString == iVector[i]->iString) + { + return *iVector[i]; + } + } + CTzCpString* aNewString = new CTzCpString(iDocument); + aNewString->iString = aString; + iVector.push_back(aNewString); + return *iVector[iVector.size() -1]; + } + +//============================================================================ +// CTzCpStringsTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpStringTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } +//============================================================================ +// CTzCpRegionsTable::CTzCpRegionsTable +//============================================================================ +CTzCpRegionsTable::CTzCpRegionsTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } + +//============================================================================ +// CTzCpRegionsTable::ExternaliseL +//============================================================================ +void CTzCpRegionsTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToRegionalZonesTable = aFilestream.tellp(); + //Loop through all the regions, externalising the regional zone index + TUint16 numRegions = iVector.size(); + aFilestream.write((char*)&numRegions,sizeof(numRegions)); + + TUint16 numberOfZones = 0; + TUint16 zoneOffset = 0; + + for (int x = 0; x < numRegions;x++) + { + iVector[x]->iRegionalZonesIndex->ExternaliseL(aFilestream); + } + + //Externalise the regions + iDocument.DbHeader()->iOffsetToRegionsTable = aFilestream.tellp(); + aFilestream.write((char*)&numRegions,sizeof(numRegions)); + for (x = 0; x < numRegions;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } +//============================================================================ +// CTzCpRegionsTable::GetRegion +// Uses the region name index (from the strings table) to determine if we +// already have an existing CTzCpRegion for this region. If we do, we return +// this. If we don't, we create a new pointer, add to iRegions and return +//============================================================================ +CTzCpRegion& CTzCpRegionsTable::GetRegion(CTzCpString& aRegionNameRef) + { + int size = iVector.size(); + for (int x = 0; x < size; x++) + { + if (iVector[x]->iRegionNameRef->iString == aRegionNameRef.iString) + { + return *iVector[x]; + } + } + CTzCpRegion* aNewRegion = new CTzCpRegion(iDocument); + aNewRegion->iRegionNameRef = &aRegionNameRef; + iVector.push_back(aNewRegion); + return *aNewRegion; + } + +//============================================================================ +// CTzCpRegionsTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpRegionsTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } + +//============================================================================ +// CTzCpRuleUsesTable::CTzCpRuleUsesTable +//============================================================================ +CTzCpRuleUsesTable::CTzCpRuleUsesTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpRuleUsesTable::AssembleL +//============================================================================ +CTzCpRuleUse& CTzCpRuleUsesTable::AssembleL(CTZNode& aNode) + { + //Create the RuleUse + CTzCpRuleUse* aRuleUse = new CTzCpRuleUse(iDocument); + aRuleUse->AssembleL(aNode); + //Add the Rule Use to the ruleuse collection + return AddRuleUse(aRuleUse); + } +//============================================================================ +// CTzCpRuleUsesTable::AddRuleUse +// Adds a rule use to the rule use table and returns a reference to it +//============================================================================ +CTzCpRuleUse& CTzCpRuleUsesTable::AddRuleUse(CTzCpRuleUse* aRuleUse) + { + iVector.push_back(aRuleUse); + return *iVector[iVector.size() - 1]; + } +//============================================================================ +// CTzCpRuleUsesTable::ExternaliseL +// Write the rule use table to a file +//============================================================================ +void CTzCpRuleUsesTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToRuleUsesTable = aFilestream.tellp(); + //Write number of rule uses + TUint16 numRuleUses = iVector.size(); + aFilestream.write((char*)&numRuleUses,sizeof(numRuleUses)); + + for (int x = 0; x < numRuleUses; x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } + +//============================================================================ +// CTzCpRuleUsesTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpRuleUsesTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } + +//============================================================================ +// CTzCpZonesTable::CTzCpZonesTable +//============================================================================ +CTzCpZonesTable::CTzCpZonesTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } + +//============================================================================ +// CTzCpZonesTable::ExternaliseL +//============================================================================ +void CTzCpZonesTable::ExternaliseL(ofstream& aFilestream) + { + // sort zones by location ID + sort(iVector.begin(), iVector.end(), CTzCpZone::SLocationIdSort()); + + TUint16 numZones = iVector.size(); + // write out zones data to database + iDocument.DbHeader()->iOffsetToZones = aFilestream.tellp(); + for (int x = 0; x < numZones; x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + + // write out the zone table to database + iDocument.DbHeader()->iOffsetToZonesTable = aFilestream.tellp(); + aFilestream.write((char*)&numZones,sizeof(numZones)); + TUint16 zoneOffset; + for (x = 0; x < numZones; x++) + { + zoneOffset = iVector[x]->iOffset; + aFilestream.write((char*)&zoneOffset,sizeof(zoneOffset)); + } + } +//============================================================================ +// CTzCpZonesTable::GetZone +// Uses the id of the zone name in the string table to determine if we already +// have created a CTzCpZone object for this zone. If it exists we return this +// otherwise we create a new zone, add it to iZones and return +// aIndex contains the index of the zone to use in the vector +// If addZone is false we do not add a new zone, just set aIndex -1 +//============================================================================ +CTzCpZone* CTzCpZonesTable::GetZone(CTzCpString& aZoneRef, CTzCpString& aRegionRef,bool addZone) + { + int size = iVector.size(); + for (int x = 0; x < size; x++) + { + string zoneTestString = iVector[x]->iZoneNameRef->iString; + string regionTestString = iVector[x]->iRegionNameRef->iString; + if ((iVector[x]->iZoneNameRef->iString == aZoneRef.iString) && (iVector[x]->iRegionNameRef->iString == aRegionRef.iString)) + { + CTzCpZone* zone = iVector[x]; + return zone; + } + } + if (addZone) + { + CTzCpZone* aNewZone = new CTzCpZone(iDocument); + aNewZone->iZoneNameRef = &aZoneRef; + aNewZone->iRegionNameRef = &aRegionRef; + iVector.push_back(aNewZone); + return aNewZone; + } + return NULL; + + } + +CTzCpZone* CTzCpZonesTable::GetZone(std::string& aZoneName) + { + int slashPos = aZoneName.find('/'); + int length = aZoneName.length(); + CTzCpString* regString = new CTzCpString(iDocument); + CTzCpString* zoneString = new CTzCpString(iDocument); + if (slashPos > 0) + { + regString->iString = aZoneName.substr(0,slashPos); + zoneString->iString = aZoneName.substr(slashPos+1,length-1); + } + else + { + regString->iString = ""; + zoneString->iString = aZoneName; + } + + CTzCpZone* zone = GetZone(*zoneString,*regString,false); + + return zone; + } + +//============================================================================ +// CTzCpZonesTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpZonesTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } + +//============================================================================ +// CTzCpStdTimeAlignmentsTable::CTzCpStdTimeAlignmentsTable +//============================================================================ +CTzCpStdTimeAlignmentsTable::CTzCpStdTimeAlignmentsTable(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpStdTimeAlignmentsTable::AddTimeAlignment +//============================================================================ +CTzCpStdTimeAlignment& CTzCpStdTimeAlignmentsTable::AddTimeAlignment(CTzCpString& aTimeZoneFormatName) + { + CTzCpStdTimeAlignment* aNewTimeAlignment = new CTzCpStdTimeAlignment(iDocument); + iVector.push_back(aNewTimeAlignment); + return *aNewTimeAlignment; + } + +//============================================================================ +// CTzCpStdTimeAlignmentsTable::ExternaliseL +// Write the time alignments to file +//============================================================================ +void CTzCpStdTimeAlignmentsTable::ExternaliseL(ofstream& aFilestream) + { + iDocument.DbHeader()->iOffsetToStdTimeAlignmentsTable = aFilestream.tellp(); + //Write number of time alignments + TUint16 numTimeAlignments = iVector.size(); + aFilestream.write((char*)&numTimeAlignments,sizeof(numTimeAlignments)); + + for (int x = 0; x < numTimeAlignments;x++) + { + iVector[x]->ExternaliseL(aFilestream); + } + } + +//============================================================================ +// CTzCpStdTimeAlignmentsTable::RemoveUnreferencedEntities +// Iterate through the vector of entities, removing all entities with a reference count of 0 +//============================================================================ +void CTzCpStdTimeAlignmentsTable::RemoveUnreferencedEntities() + { + iVector.erase(std::remove_if(iVector.begin(),iVector.end(),SEntityCheck()),iVector.end()); + } +//============================================================================ +// End of file +//============================================================================