tzpcside/tzcompiler/Source/TzTables.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// 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
//============================================================================