diff -r 000000000000 -r 2e3d3ce01487 tzpcside/tzcompiler/Source/TzEntities.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tzpcside/tzcompiler/Source/TzEntities.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,500 @@ +// 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 "TzEntities.h" +#include "TzTables.h" +#include "TZNode.h" +#include "TZDocument.h" +#include "TzHelpers.h" +#include +#include +#include +#include +using namespace std; +//============================================================================ +// CTzCpString::CTzCpString +//============================================================================ +CTzCpString::CTzCpString(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpString::ExternaliseL +//============================================================================ +void CTzCpString::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToStringTable; + TUint8 stringLength = iString.length(); + aFilestream.write((char*)&stringLength,sizeof(stringLength)); + aFilestream << iString.c_str(); + } +//============================================================================ +// CTzCpRegion::CTzCpRegion +//============================================================================ +CTzCpRegion::CTzCpRegion(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + iRegionalZonesIndex = new CTzCpRegionalZonesIndex(aDocument); + } +//============================================================================ +// CTzCpRegion::~CTzCpRegion +//============================================================================ +CTzCpRegion::~CTzCpRegion() + { + for (int x = 0; x < iRegionalZonesIndex->iZoneIndex.size();++x) + { + iRegionalZonesIndex->iZoneIndex[x]->DecrRefCount(); + } + + delete iRegionalZonesIndex; + } + +//============================================================================ +// CTzCpRegion::ExternaliseL +//============================================================================ +void CTzCpRegion::ExternaliseL(ofstream& aFilestream) + { + iPersistedEntity.iOffsetToRegionName = iRegionNameRef->iOffset; + iPersistedEntity.iOffsetToRegionalZoneIndex = iRegionalZonesIndex->iOffset; + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)); + } +//============================================================================ +// CTzCpRuleUse::CTzCpRuleUse +// RuleUse constructor. +//============================================================================ +CTzCpRuleUse::CTzCpRuleUse(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpRuleUse::~CTzCpRuleUse +//============================================================================ +CTzCpRuleUse::~CTzCpRuleUse() + { + iRuleLetterPtr->DecrRefCount(); + iRuleDefinitionPtr->DecrRefCount(); + } +//============================================================================ +// CTzCpRuleUse::AssembleL +// Populates the CTzCpRuleUse from the current node. +// RuleUse 'To' field may contain 'only' in the olsen files +// This is to show the rule was in use for that year only. In this case +// we change the to field to match the from field. +//============================================================================ +void CTzCpRuleUse::AssembleL(CTZNode& aNode) + { + iPersistedEntity.iFromYear = atoi(aNode.NodeList()[2]->iValue.c_str()); + if (aNode.NodeList()[3]->iValue.c_str()[0] == 'o') + { + iPersistedEntity.iUntilYear = iPersistedEntity.iFromYear; + } + else if (aNode.NodeList()[3]->iValue.c_str()[0] == 'm') + { + iPersistedEntity.iUntilYear = KMaxTUint16; + } + else + { + iPersistedEntity.iUntilYear = atoi(aNode.NodeList()[3]->iValue.c_str()); + } + } +//============================================================================ +// CTzCpLink::CTzCpLink +//============================================================================ +CTzCpLink::CTzCpLink(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpLink::AssembleL +//============================================================================ +int CTzCpLink::AssembleL(CTZNode& aNode) + { + //Add the from value into the string table as is + //aNode.iNodeList[ELinkFormatFromZone]->iValue; + //Split the 'To' value into its region/zone parts + //'Region' is first part of a zone identity. eg 'Europe' in 'Europe/London' + //'Zone' is second part of a zone identity. eg 'London' in 'Europe/London' + string linkString = aNode.NodeList()[ELinkFormatToZone]->iValue; + string fromString = aNode.NodeList()[ELinkFormatFromZone]->iValue; + int slashChar = linkString.find('/',0); + iLinkString = &iDocument.StringTable()->AddString(fromString); + iLinkString->IncrRefCount(); + + if (slashChar > 0) + { + iRegionString = &iDocument.StringTable()->AddString(linkString.substr(0,slashChar)); + } + else + { + iRegionString = &iDocument.StringTable()->AddString(""); + } + iRegionString->IncrRefCount(); + + iZoneString = &iDocument.StringTable()->AddString(linkString.substr(slashChar+1)); + iZoneString->IncrRefCount(); + return 0; + } +//============================================================================ +// CTzCpLink::ExternaliseL +//============================================================================ +void CTzCpLink::ExternaliseL(ofstream& aFilestream) + { + iPersistedEntity.iOffsetToLinkName = iLinkString->iOffset; + iPersistedEntity.iOffsetToZone = iLinkedZoneOffset->iOffset; + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)); + } +//============================================================================ +// CTzCpRuleUse::ExternaliseL +//============================================================================ +void CTzCpRuleUse::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToRuleUsesTable; + iPersistedEntity.iOffsetToRuleDefinition = iRuleDefinitionPtr->iOffset; + iPersistedEntity.iOffsetToRuleLetterString = iRuleLetterPtr->iOffset; + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)); + } +//============================================================================ +// CTzCpRuleDefinition::CTzCpRuleDefinition +//============================================================================ +CTzCpRuleDefinition::CTzCpRuleDefinition(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpRuleDefinition::AssembleL +// Populates the CTzCpRuleDefinition from the current node +//============================================================================ +int CTzCpRuleDefinition::AssembleL(CTZNode& aNode) + { + //Set the time offset + //Assuming that the 'SAVE' field in a rule is of the format H:MM + string tmpString = aNode.NodeList()[ERuleFormatSave]->iValue; + int breakAt = tmpString.find_first_of(':'); + int hours = atoi(tmpString.c_str()); + int minutes = 0; + if (tmpString.length() > 1) + { + minutes = atoi(tmpString.substr(2).c_str()); + } + iPersistedEntity.iStdTimeOffset = (hours*60) + minutes; + + //Set the month ( 0 - 11) + iPersistedEntity.iMonth = CTzCpHelpers::GetMonth(aNode.NodeList()[ERuleFormatIn]->iValue); + + //Set the day rule + tmpString = aNode.NodeList()[ERuleFormatOn]->iValue; + string searchDayAfterString = ">="; + string searchDayBeforeString = "<="; + + if (tmpString.c_str()[0] == 'l') + { + iPersistedEntity.iDayRule = ETzDayInLastWeekOfMonth; + } + else if (strstr(tmpString.c_str(),searchDayAfterString.c_str()) != NULL) + { + iPersistedEntity.iDayRule = ETzDayAfterDate; + } + else if (strstr(tmpString.c_str(),searchDayBeforeString.c_str()) != NULL) + { + iPersistedEntity.iDayRule = ETzDayBeforeDate; + } + else + { + iPersistedEntity.iDayRule = ETzFixedDate; + } + + //Set the day of month. This is only required if the day rule is + //ETzFixedDate, EDayBeforeDate or EDayAfterDate. Defaults to 0. + TInt tmpDay; + switch (iPersistedEntity.iDayRule) + { + case ETzFixedDate: + tmpDay = atoi(tmpString.c_str()); + tmpDay = tmpDay ? tmpDay-1 : 0; // OG: zero-based Day (as used in TDateTime in Symbian OS) + iPersistedEntity.iDayOfMonth = tmpDay; + break; + case ETzDayBeforeDate: + case ETzDayAfterDate: + tmpDay = atoi(tmpString.substr(5).c_str()); + tmpDay = tmpDay ? tmpDay-1 : 0; // OG: zero-based Day (as used in TDateTime in Symbian OS) + iPersistedEntity.iDayOfMonth = tmpDay; + break; + default: + iPersistedEntity.iDayOfMonth = 0; + break; + } + + //Set the day of the week. This only applies if day rule != ETzFixedDate + iPersistedEntity.iDayOfWeek = CTzCpHelpers::GetDay(tmpString); + + //Set the time of change (in minutes) + tmpString = aNode.NodeList()[ERuleFormatAt]->iValue; + iPersistedEntity.iTimeOfChange = CTzCpHelpers::GetTimeOfDayInMinutes(tmpString); + + //set the time reference + iPersistedEntity.iTimeReference = CTzCpHelpers::GetTimeReference(tmpString); + + //Spare flags - these will probably be used for implementing write access + //if required + //iPersistedEntity.iReferenceCount = 0; //Unused for now + //iPersistedEntity.iStatus = 0; //Unused for now + return 0; + } +//============================================================================ +// CTzCpRuleDefinition::ExternaliseL +//============================================================================ +void CTzCpRuleDefinition::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToRuleDefinitionsTable; + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)); + } +//============================================================================ +// CTzCpRuleSet::CTzCpRuleSet +//============================================================================ +CTzCpRuleSet::CTzCpRuleSet(CTZDocument& aDocument,std::string aRuleSetName) + : CPersistedEntityWrapper(aDocument) , iName(aRuleSetName) + { + } +//============================================================================ +// CTzCpRuleSet::~CTzCpRuleSet +//============================================================================ +CTzCpRuleSet::~CTzCpRuleSet() + { + int size = RuleUses().size(); + for (int x = 0; x < size;x++) + { + iVector[x]->DecrRefCount(); + } + } + +//============================================================================ +// CTzCpRuleSet::ExternaliseL +//============================================================================ +void CTzCpRuleSet::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToRuleSetsTable; + iPersistedEntity.iNumberOfRuleUses = iVector.size(); + + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)-sizeof(iPersistedEntity.iOffsetsToRuleUses)); + TUint16 ruleUseOffset; + for (int x = 0; x < iPersistedEntity.iNumberOfRuleUses;x++) + { + ruleUseOffset = iVector[x]->iOffset; + aFilestream.write((char*)&ruleUseOffset,sizeof(ruleUseOffset)); + } + } +//============================================================================ +// CTzCpRuleSet::AddRuleUse +// Adds the index of the CTzCpRuleUse in the rule use table +// to the collection of rule uses +//============================================================================ +void CTzCpRuleSet::AddRuleUse(CTzCpRuleUse& aRuleUse) + { + iVector.push_back(&aRuleUse); //The address of the ruleuse + } +//============================================================================ +// CTzCpRegionalZonesIndex::CTzCpRegionalZoneIndex +//============================================================================ +CTzCpRegionalZonesIndex::CTzCpRegionalZonesIndex(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } + +//============================================================================ +// CTzCpRegionalZonesIndex::ExternaliseL +//============================================================================ +void CTzCpRegionalZonesIndex::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToRegionalZonesTable; + + // sort zone index alphabetically before externalising it + sort(iZoneIndex.begin(),iZoneIndex.end(),CTzCpZone::SZoneNameSort()); + + iPersistedEntity.iNumberOfZones = iZoneIndex.size(); + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity) - sizeof(iPersistedEntity.iOffsetsToZones)); + //Write out the zone offsets + for (int x = 0; x < iPersistedEntity.iNumberOfZones;x++) + { + TUint16 zoneOffset = iZoneIndex[x]->iOffset; + aFilestream.write((char*)&zoneOffset,sizeof(zoneOffset)); + } + } +//============================================================================ +// CTzCpRegionalZonesIndex::AddZoneIndex +// We add the address of the reference to avoid a double deletion - +// this zone will already +//============================================================================ +void CTzCpRegionalZonesIndex::AddZoneIndex(CTzCpZone& aZoneRef) + { + iZoneIndex.push_back(&aZoneRef); + } +//============================================================================ +// CTzCpZone::CTzCpZone +//============================================================================ +CTzCpZone::CTzCpZone(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpZone::~CTzCpZone +// When we destroy a zone, we need to decrement all its referenced entity +// reference counts by 1. +//============================================================================ +CTzCpZone::~CTzCpZone() + { + iRegionNameRef->DecrRefCount(); + iZoneNameRef->DecrRefCount(); + + for (int x = 0; x < iTimeAlignments.size();++x) + { + iTimeAlignments[x]->DecrRefCount(); + } + } + +//============================================================================ +// CTzCpZone::ExternaliseL +//============================================================================ +void CTzCpZone::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToZones; + iPersistedEntity.iLocationId = iLocationId; + iPersistedEntity.iOffsetToZoneName = iZoneNameRef->iOffset; + iPersistedEntity.iOffsetToRegionName = iRegionNameRef->iOffset; + iPersistedEntity.iNumberOfStdTimeAlignments = iTimeAlignments.size(); + + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)-sizeof(iPersistedEntity.iOffsetsToTimeAlignments)); + + //Externalise the time alignment offsets + for (int x = 0; x < iPersistedEntity.iNumberOfStdTimeAlignments; x++) + { + TUint16 stdoffset = iTimeAlignments[x]->iOffset; + aFilestream.write((char*)&stdoffset,sizeof(stdoffset)); + } + } +//============================================================================ +// CTzCpStdTimeAlignment::CTzCpStdTimeAlignment +//============================================================================ +CTzCpStdTimeAlignment::CTzCpStdTimeAlignment(CTZDocument& aDocument) + : CPersistedEntityWrapper(aDocument) + { + } +//============================================================================ +// CTzCpStdTimeAlignment::~CTzCpStdTimeAlignment +// When we destroy a CTzCpStdTimeAlignment we need to decrement all its +// referenced entity reference counts by 1. +//============================================================================ +CTzCpStdTimeAlignment::~CTzCpStdTimeAlignment() + { + iOffsetToTimeZoneFormatName->DecrRefCount(); + + for (int x = 0; x < iOffsetsToTimeZonesShortNames.size();++x) + { + iOffsetsToTimeZonesShortNames[x]->DecrRefCount(); + } + iRuleSet->DecrRefCount(); + } +//============================================================================ +// CTzCpStdTimeAlignment::AssembleL +// Populates the CTzCpStdTimeAlignment from the current node +//============================================================================ +int CTzCpStdTimeAlignment::AssembleL(CTZNode& aNode) + { + string tmpString; + //Until Year + if (EZoneFormatUntilYear >= aNode.NodeList().size()) + { + iPersistedEntity.iUntilYear = KMaxYear; + } + else + { + iPersistedEntity.iUntilYear = atoi(aNode.NodeList()[EZoneFormatUntilYear]->iValue.c_str()); + } + //Until Month + if (EZoneFormatUntilMonth >= aNode.NodeList().size()) + { + iPersistedEntity.iUntilMonth = 0; + } + else + { + tmpString = aNode.NodeList()[EZoneFormatUntilMonth]->iValue; + if (tmpString.empty()) + iPersistedEntity.iUntilMonth = 0; + else + iPersistedEntity.iUntilMonth = CTzCpHelpers::GetMonth(tmpString); + } + //Until DayOfMonth + if (EZoneFormatUntilDay >= aNode.NodeList().size()) + { + iPersistedEntity.iUntilDayOfMonth = 0; + } + else + { + tmpString = aNode.NodeList()[EZoneFormatUntilDay]->iValue; + TInt tmpDay = atoi(aNode.NodeList()[EZoneFormatUntilDay]->iValue.c_str()); + tmpDay = tmpDay ? tmpDay-1 : 0; // zero-based Day (as used in TDateTime in Symbian OS) + iPersistedEntity.iUntilDayOfMonth = tmpDay; + } + //Until minutes + //Until Time Reference + if (EZoneFormatUntilMinutes >= aNode.NodeList().size()) + { + iPersistedEntity.iUntilTimeInMinutes = 0; + iPersistedEntity.iUntilTimeReference = 0; + } + else + { + tmpString = aNode.NodeList()[EZoneFormatUntilMinutes]->iValue; + iPersistedEntity.iUntilTimeInMinutes = CTzCpHelpers::GetTimeOfDayInMinutes(tmpString); + iPersistedEntity.iUntilTimeReference = CTzCpHelpers::GetTimeReference(tmpString); + } + //GMTOffset in minutes + tmpString = aNode.NodeList()[EZoneFormatGMTOffset]->iValue; + iPersistedEntity.iUtcOffset = CTzCpHelpers::GetTimeOfDayInMinutes(tmpString); + + //Set these in the document after completion. + //Offset to ruleset + iPersistedEntity.iOffsetToRuleSet = 0; + //offset to timezoneformat + iPersistedEntity.iOffsetToTimeZoneFormatName = 0; + return 0; + } +//============================================================================ +// CTzCpStdTimeAlignment::ExternaliseL +//============================================================================ +void CTzCpStdTimeAlignment::ExternaliseL(ofstream& aFilestream) + { + iOffset = (int)aFilestream.tellp() - iDocument.DbHeader()->iOffsetToStdTimeAlignmentsTable; + //Retrieve the ruleset offset + iPersistedEntity.iOffsetToRuleSet = iRuleSet->iOffset; + //Retrieve the time zone format name offset + iPersistedEntity.iOffsetToTimeZoneFormatName = iDocument.StringTable()->Strings()[iPersistedEntity.iOffsetToTimeZoneFormatName]->iOffset; + //Set the number of time zones + iPersistedEntity.iNumberOfTimeZones = iOffsetsToTimeZonesShortNames.size(); + + aFilestream.write((char*)&iPersistedEntity,sizeof(iPersistedEntity)-sizeof(iPersistedEntity.iOffsetsToTimeZones)); + //Write the time zone offsets + int size = iOffsetsToTimeZonesShortNames.size(); + for (int x = 0; x < size; x++) + { + TUint16 offsetToTimeZone = iOffsetsToTimeZonesShortNames[x]->iOffset; + aFilestream.write((char*)&offsetToTimeZone,sizeof(offsetToTimeZone)); + } + } +//============================================================================ +// End of file +//============================================================================