--- /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 <algorithm> // sort
+#include <iostream>
+#include <fstream>
+#include <cstdio>
+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<CTzCpLink*>::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
+//============================================================================