tzpcside/tzcompiler/Source/TzTables.cpp
changeset 0 2e3d3ce01487
--- /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
+//============================================================================