--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/commsfwtools/preparedefaultcommsdatabase/Tools/ced/src/CXMLContentHandler.cpp Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1594 @@
+// Copyright (c) 2003-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:
+//
+
+#include <e32test.h>
+#include <f32file.h>
+#include <stringpool.h>
+#include "dbdef.h"
+#include <xml/documentparameters.h>
+#include <xml/taginfo.h>
+#include <xml/attribute.h>
+#include "CXMLContentHandler.h"
+
+#include "filedump.h"
+extern CFileDump* gMsg; // logging
+using namespace Xml;
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+extern TBool gDeprecatedFields;
+#endif
+
+//anonymous namespace
+//These things are needed only here... Don't mess up the global namespace
+namespace
+ {
+ // The names of the tables to modify
+ const TText* const modTable[] =
+ {
+ _S("IAPTable"),
+ _S("IAPTable"),
+ _S("IAPTable"),
+ _S("IAPTable"),
+ _S("IAPTable"),
+
+ _S("ProxyTable"),
+
+ _S("WAPIPBearerTable"),
+ _S("WAPIPBearerTable"),
+
+ _S("WAPSMSBearerTable"),
+
+ _S("VpnServiceTable"),
+ _S("VpnServiceTable"),
+
+ _S("ConnectionPreferencesTable"),
+
+ _S("GlobalSettingsTable"),
+ _S("GlobalSettingsTable"),
+ _S("GlobalSettingsTable"),
+ _S("GlobalSettingsTable"),
+ _S("OutgoingGPRSTable"),
+
+ _S("WLANServiceExtensionTable"),
+
+ _S("EAPSecuritySettingsTable"),
+
+ _S("TunnelledEAPSettingsTable")
+
+ };
+
+ // The names of the parameters to modify
+ const TText* const modParam[] =
+ {
+ // IAPTable
+ _S("IAPService"),
+ _S("IAPBearer"),
+ _S("IAPNetwork"),
+ _S("LocationRef"),
+ _S("ChargecardRef"),
+
+ // ProxyRef
+ _S("ISPRef"),
+
+ // WAPIPBearerTable
+ _S("AccessPoint"),
+ _S("IAPRef"),
+
+ // WAPSMSBearerTable
+ _S("AccessPoint"),
+
+ // VpnServiceTable
+ _S("HomeIAP"),
+ _S("HomeNetwork"),
+
+ // ConnectionPreferencesTable
+ _S("IAPRef"),
+
+ // GlobalSettingsTable
+ _S("DefaultNetwork"),
+ _S("LocationForDataAndFax"),
+ _S("LocationForPhoneServicesAndSMS"),
+ _S("WAPAccess"),
+
+ // OutgoingGPRSTable
+ _S("UmtsR99QoSAndOnRef"),
+
+ //WLANServiceExtensionTable
+ _S("Wlan_Security_Data"),
+
+ //EAPSecuritySettingsTable
+ _S("EAP_Method_Data"),
+
+ //TunnelledEAPSettingsTable
+ _S("Tun_EAP_Method_Data")
+ };
+
+ // The new names of the modified parameters
+ const TText* const newModParam[] =
+ {
+ // IAPTable
+ _S("IAPService"),
+ _S("IAPBearer"),
+ _S("IAPNetwork"),
+ _S("Location"),
+ _S("Chargecard"),
+
+ // ProxyRef
+ _S("ISP"),
+
+ // WAPIPBearerTable
+ _S("AccessPointId"),
+ _S("IAP"),
+
+ // WAPSMSBearerTable
+ _S("AccessPointId"),
+
+ // VpnServiceTable
+ _S("HomeIAP"),
+ _S("HomeNetwork"),
+
+ // ConnectionPreferencesTable
+ _S("IAP"),
+
+ // GlobalSettingsTable
+ _S("DefaultNetwork"),
+ _S("LocationForDataAndFax"),
+ _S("LocationForPhoneServicesAndSMS"),
+ _S("WAPAccessPoint"),
+
+ // OutgoingGPRSTable
+ _S("UmtsR99QoSAndOn"),
+
+ //WLANServiceExtensionTable
+ _S("Wlan_Security_Data"),
+
+ //EAPSecuritySettingsTable
+ _S("EAP_Method_Data"),
+
+ //TunnelledEAPSettingsTable
+ _S("Tun_EAP_Method_Data")
+ };
+
+ /**
+ The names of the new parameters to add which indicate the
+ table where the table entry reference is
+ */
+ const TText* const typeParam[] =
+ {
+ _S("IAPServiceType"),
+ _S("IAPBearerType"),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S("ProxyServiceType"),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S(""),
+ _S("")
+ };
+
+ const TInt numMods = 20;
+
+ const TText* const noNameTables[] =
+ {
+ _S("GlobalSettingsTable"),
+ _S("ProxyTable"),
+ _S("AgentLookupTable"),
+ _S("WAPIPBearerTable"),
+ _S("WAPSMSBearerTable"),
+ _S("SecureSocketTable"),
+ _S("BTDefaultTable"),
+ _S("BTDeviceTable"),
+ _S("BTPersistTable"),
+ _S("BTSecurityTable"),
+ _S("ConnectionPreferencesTable")
+ };
+
+ const TInt numNoNameTables = 11;
+
+ /**
+ * These two arrays (tableNamesForPairing, tmdbElementsForPairing) are needed because an
+ * RHashMap is built up to handle these pairs. It is needed to serch for the table ID
+ * based on the table name read form the xml config file.
+ */
+
+ const TText* const tableNamesForPairing[] =
+ {
+ _S("NetworkTable"), //KCDTIdNetworkRecord
+ _S("IAPTable"), //KCDTIdIAPRecord
+ _S("ModemBearerTable"), //KCDTIdModemBearerRecord
+ _S("LANBearerTable"), //KCDTIdLANBearerRecord
+ _S("LANServiceTable"), //KCDTIdLANServiceRecord
+ _S("DialInISPTable"), //KCDTIdDialInISPRecord
+ _S("DialOutISPTable"), //KCDTIdDialOutISPRecord
+ _S("AgentLookupTable"), //KCDTIdAgentLookupRecord
+ _S("ChargecardTable"), //KCDTIdChargecardRecord
+ _S("ConnectionPreferencesTable"), //KCDTIdConnectionPrefsRecord
+ _S("GlobalSettingsTable"), //KCDTIdGlobalSettingsRecord
+ _S("IncomingGPRSTable"), //KCDTIdIncomingGprsRecord
+ _S("OutgoingGPRSTable"), //KCDTIdOutgoingGprsRecord
+ //_S("DefaultGPRSTable"), //<NOKIA magic...>
+ _S("ProxyTable"), //KCDTIdProxiesRecord
+ _S("LocationTable"), //KCDTIdLocationRecord
+ _S("SecureSocketTable"), //KCDTIdSSProtoRecord
+ //_S("BTDeviceTable"), //<not used anymore>
+ //_S("BTPersistTable"), //<not used anymore>
+ //_S("BTSecurityTable"), //<not used anymore>
+ //_S("BTDefaultTable"), //<not used anymore>
+ _S("WAPAccessPointTable"), //KCDTIdWAPAccessPointRecord
+ _S("WAPIPBearerTable"), //KCDTIdWAPIPBearerRecord
+ _S("WAPSMSBearerTable"), //KCDTIdWAPSMSBearerRecord
+ _S("VirtualBearerTable"), //KCDTIdVirtualBearerRecord
+ _S("VpnServiceTable"), //KCDTIdVPNServiceRecord
+ _S("WLANServiceExtensionTable"), //KCDTIdWLANServiceExtRecord
+ _S("PANServiceExtensionsTable"), //KCDTIdPANServiceExtRecord
+ _S("EAPSecuritySettingsTable"), //KCDTIdEAPSecRecord
+ _S("TunnelledEAPSettingsTable"), //KCDTIdTunEAPRecord
+ _S("EAPTLSSettingsTable"), //KCDTIdEAPTLSRecord
+#ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ _S("LEAPSettingsTable") //KCDTIdLEAPRecord
+#else
+ _S("LEAPSettingsTable"), //KCDTIdLEAPRecord
+ _S("PolicySelectorTable"), //KCDTIdPolicySelectorRecord
+ _S("PolicySelector2QosParametersTable"), //KCDTIdPolicySelector2ParamsRecord
+ _S("GenericQosTable") //KCDTIdGenericQosRecord
+#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ };
+
+
+ const TMDBElementId tmdbElementsForPairing[] =
+ {
+ KCDTIdNetworkRecord,
+ KCDTIdIAPRecord,
+ KCDTIdModemBearerRecord,
+ KCDTIdLANBearerRecord,
+ KCDTIdLANServiceRecord,
+ KCDTIdDialInISPRecord,
+ KCDTIdDialOutISPRecord,
+ KCDTIdAgentLookupRecord,
+ KCDTIdChargecardRecord,
+ KCDTIdConnectionPrefsRecord,
+ KCDTIdGlobalSettingsRecord,
+ KCDTIdIncomingGprsRecord,
+ KCDTIdOutgoingGprsRecord,
+ //NOKIA magic...>,
+ KCDTIdProxiesRecord,
+ KCDTIdLocationRecord,
+ KCDTIdSSProtoRecord,
+ //not used anymore>,
+ //not used anymore>,
+ //not used anymore>,
+ //not used anymore>,
+ KCDTIdWAPAccessPointRecord,
+ KCDTIdWAPIPBearerRecord,
+ KCDTIdWAPSMSBearerRecord,
+ KCDTIdVirtualBearerRecord,
+ KCDTIdVPNServiceRecord,
+ KCDTIdWLANServiceExtRecord,
+ KCDTIdPANServiceExtRecord,
+ KCDTIdEAPSecRecord,
+ KCDTIdTunEAPRecord,
+ KCDTIdEAPTLSRecord,
+#ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ KCDTIdLEAPRecord
+#else
+ KCDTIdLEAPRecord,
+ KCDTIdPolicySelectorRecord,
+ KCDTIdPolicySelector2ParamsRecord,
+ KCDTIdGenericQosRecord
+#endif //SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ };
+
+#ifndef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ const TInt KPairNumber = 27; //number of pairs in the above arrays
+#else
+ const TInt KPairNumber = 30; //number of pairs in the above arrays
+#endif
+
+ TUint32 DoHash(const TPtrC& aText)
+ {
+ return DefaultHash::Des16(aText);
+ }
+
+ TBool AreTheKeysIdentical(const TPtrC& aKey1, const TPtrC& aKey2)
+ {
+ return (aKey1 == aKey2);
+ }
+ } //end of anonymous namespace
+
+//
+// CXMLContentHandler
+//
+const TInt CXMLContentHandler::KExpectedLeaveCode = 1234;
+
+CXMLContentHandler* CXMLContentHandler::NewL( CXMLDatabase* aXmlDb,
+ const TBool aForceFlag,
+ const TBool aAppendFlag )
+ {
+ CXMLContentHandler* self = new(ELeave) CXMLContentHandler(aXmlDb,aForceFlag,aAppendFlag);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CXMLContentHandler::CXMLContentHandler(CXMLDatabase* aXmlDb,
+ const TBool aForceFlag,
+ const TBool aAppendFlag) :
+ iLeaveOnStartElement(EFalse),
+ iNumElements(0),
+ iNumSkippedEntities(0),
+ iNumPrefixMappings(0),
+ iNumPrefixUnmappings(0),
+ iError(KErrNone),
+ iXmlDb(aXmlDb),
+ iForceXMLProcessing(aForceFlag),
+ isInAppendMode(aAppendFlag),
+ iXMLContentState(ENone)
+ {
+ iCurrentTableName.Copy(_L(""));
+ iCurrentRecordName.Copy(_L(""));
+ iCurrentParameterValue.Copy(_L(""));
+ iCurrentParameter.Copy(_L(""));
+ }
+
+void CXMLContentHandler::ConstructL()
+ {
+#ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
+ iCmdbSession = CMDBSession::NewL(KCDVersion1_2);
+#else
+ iCmdbSession = CMDBSession::NewL(KCDVersion1_1);
+#endif
+
+ THashFunction32<TPtrC> hashFunc(&DoHash);
+ TIdentityRelation<TPtrC> idRel(&AreTheKeysIdentical);
+
+ iTableNameIDpairs = new(ELeave) RHashMap<TPtrC, TMDBElementId>(hashFunc, idRel);
+ FillUpHashMapL(*iTableNameIDpairs);
+ }
+
+CXMLContentHandler::~CXMLContentHandler()
+ {
+ delete iCmdbSession;
+ iCmdbSession = NULL;
+
+ iTableNameIDpairs->Close();
+ delete iTableNameIDpairs;
+ iTableNameIDpairs = NULL;
+ }
+
+// When the beginning of the document is encountered then all counters
+// are initialised
+void CXMLContentHandler::OnStartDocumentL(const RDocumentParameters&, TInt)
+ {
+ iNumElements = 0;
+ iNumSkippedEntities = 0;
+ iNumPrefixMappings = 0;
+ iNumPrefixUnmappings = 0;
+ }
+
+void CXMLContentHandler::OnEndDocumentL(TInt)
+ {
+ }
+
+// At the beginning of an XML element we need to find out what does the element
+// represent
+void CXMLContentHandler::OnStartElementL(const RTagInfo& aInfo, const RAttributeArray& attribs, TInt)
+ {
+ if (iLeaveOnStartElement)
+ {
+ if (iNumElements++ == 0)
+ {
+ User::Leave(KExpectedLeaveCode);
+ }
+ }
+
+ iNumElements++;
+
+ // Get the name of the tag
+ //
+ const TDesC8& name = aInfo.LocalName().DesC();
+ TBuf<MAX_BUFFER_LEN> tag;
+ tag.Copy(name);
+
+ TBuf<MAX_BUFFER_LEN> thisTag;
+
+ switch (iXMLContentState)
+ {
+ case ENone:
+ {
+
+ // We avoid the "Config" and "InformationTable" tags as well as
+ // the parameters of the "InformationTable" which are not supported
+ // in this version
+ if (tag.Compare(_L("Config")) == 0)
+ {
+ gMsg->Msg(_L("Avoiding Config element"));
+ return;
+ }
+
+ if (tag.Compare(_L("InformationTable")) == 0)
+ {
+ iXMLContentState = EInDeprecatedTable;
+ iCurrentTableName.Copy(tag);
+ gMsg->Msg(_L("Start of the InformationTable element"));
+ return;
+ }
+
+ // See if this tagname is a table
+
+ TInt i = 0;
+ TBuf<MAX_BUFFER_LEN> tableName;
+ thisTag = xmlTableArray[0];
+
+
+ while (thisTag.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ tableName = thisTag;
+ tableName.Append(_L("Table"));
+
+ // Check if this is a table
+ //
+ if (tableName.Compare(tag) == 0)
+ {
+ // If the parsed element is a table then save the name of this
+ // table for later use when creating table entries
+ //
+ iXMLContentState = EInTable;
+ iCurrentTableName.Copy(tableName);
+ gMsg->Msg(_L("Located table : [%S]"), &tableName);
+ return;
+ }
+ i++;
+ thisTag = xmlTableArray[i];
+ }
+
+ // If we've got here then there must have been some weirdness in the input file, still
+ // perhaps if we carry on, we'll sort ourselves out...
+
+ gMsg->Msg(_L("ERR: Unknown or deprecated table : [%S]"), &tag);
+ iXMLContentState = EInDeprecatedTable;
+ iCurrentTableName.Copy(tag);
+ }
+ break;
+
+ case EInDeprecatedTable:
+ return;
+ case EInTable:
+ {
+ // Examine if this tagname is a record
+
+ TInt i = 0;
+ thisTag = xmlTableArray[0];
+ while (thisTag.Compare(TPtrC(NO_MORE_RECORDS)) != 0)
+ {
+ // Check whether this is a table entry
+ //
+ if (thisTag.Compare(tag) == 0)
+ {
+ // If the parsed element is a table entry then create a new CXMLTableEntry
+ // object and add it to the XML database
+
+ iXMLContentState = EInRecord;
+ iCurrentRecordName.Copy(thisTag);
+
+ CXMLTableEntry* tableEntry = CXMLTableEntry::NewL(iCurrentTableName);
+ TBuf<MAX_BUFFER_LEN> operation;
+ if(attribs.Count() == 0)
+ {
+ operation.Copy(_L("add"));
+ }
+ else
+ {
+ operation.Copy(attribs[0].Value().DesC());
+ }
+
+ tableEntry->SetOperation(operation);
+
+ gMsg->Msg(_L("Create new table entry for table : [%S] with operation (%S)"),
+ &iCurrentTableName, &operation);
+ iXmlDb->AddTableEntry(tableEntry);
+ return;
+ }
+
+ i++;
+ thisTag = xmlTableArray[i];
+ }
+
+
+ // If we've got here then there must have been some weirdness in the input file, still
+ // perhaps if we carry on, we'll sort ourselves out...
+
+ gMsg->Msg(_L("ERR: Unknown record : [%S]"), &tag);
+ if (!iForceXMLProcessing)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+ break;
+
+ case EInRecord:
+ {
+ // If the parsed element is not a table or a table entry then it
+ // represents the beginning of the specification of a table entry
+ // parameter. In this case we need to set the name of this element
+ // as a new parameter for the table entry we last created. Note that
+ // the value of the parameter will be picked by a call to the
+ // OnContentL function
+
+ iXMLContentState = EInParam;
+
+ CXMLTableEntry* lastEntry = iXmlDb->GetLastTableEntry();
+ iCurrentParameter.Copy(tag);
+ lastEntry->AddParameterL(tag, _L(""));
+ gMsg->Msg(_L("Create new parameter : [%S]"), &tag);
+
+ /**
+ Set the linking type to default - ENot_A_Link. Later on this will be
+ changed.
+ */
+ lastEntry->SetLinkType(CXMLTableEntry::ENot_A_Link);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // OnStartElementL()
+
+
+void CXMLContentHandler::OnEndElementL(const RTagInfo& aInfo, TInt)
+ {
+ // Get the name of the tag
+ const TDesC8& name = aInfo.LocalName().DesC();
+ TBuf<MAX_BUFFER_LEN> tag;
+ tag.Copy(name);
+
+ // Reset the name of the current table if we reached the end of the table
+
+ switch (iXMLContentState)
+ {
+ case EInDeprecatedTable:
+ {
+ if (tag.Compare(iCurrentTableName) == 0)
+ {
+ iCurrentTableName.Copy(_L(""));
+ gMsg->Msg(_L("Reached end of deprecated table [%S]"), &tag);
+ iXMLContentState = ENone;
+ }
+ else
+ {
+ gMsg->Msg(_L("ERR: Use of [%S] inside deprecated [%S]"), &tag, &iCurrentTableName);
+#ifdef SYMBIAN_NETWORKING_3GPPDEFAULTQOS
+ gDeprecatedFields = ETrue;
+#endif
+ }
+
+ }
+ break;
+ case EInTable:
+ {
+ iXMLContentState = ENone;
+ if (tag.Compare(iCurrentTableName) == 0)
+ {
+ iCurrentTableName.Copy(_L(""));
+ gMsg->Msg(_L("Reached end of table [%S]"), &tag);
+ }
+ else
+ {
+ gMsg->Msg(_L("Error parsing table [%S]"), &tag);
+ if (!iForceXMLProcessing)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+ }
+ break;
+
+ case EInRecord:
+ {
+ iXMLContentState = EInTable;
+ if (tag.Compare(iCurrentRecordName) == 0)
+ {
+ iCurrentRecordName.Copy(_L(""));
+ gMsg->Msg(_L("Reached end of record [%S]"), &tag);
+ }
+ else
+ {
+ gMsg->Msg(_L("Error parsing record [%S]"), &tag);
+ if (!iForceXMLProcessing)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+ }
+ break;
+
+ case EInParam:
+ {
+ iXMLContentState = EInRecord;
+ if (tag.Compare(iCurrentParameter) == 0)
+ {
+ // Pick the last table entry added to the database
+ CXMLTableEntry* lastEntry = iXmlDb->GetLastTableEntry();
+ TInt lastParamIndex = lastEntry->GetNumberParameters()-1;
+
+ // Examine to see if the content is simply the return
+ // character which indicates that there is no assigned
+ // value for this parameter
+ TInt loc = iCurrentParameterValue.Locate('\n');
+
+ if (loc == 0)
+ {
+ lastEntry->RemoveParameter(lastParamIndex);
+ return;
+ }
+
+ // Set the value of the last parameter for this table entry
+ lastEntry->SetParameterValue(lastParamIndex, iCurrentParameterValue);
+
+ gMsg->Msg(_L("Set parameter value to : [%S]"), &iCurrentParameterValue);
+ iCurrentParameterValue.Copy(_L(""));
+ }
+ else
+ {
+ gMsg->Msg(_L("Error parsing parameter [%S]"), &tag);
+ if (!iForceXMLProcessing)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // OnEndElementL()
+
+
+void CXMLContentHandler::OnContentL(const TDesC8& aContent, TInt)
+ {
+ // If we are currently processing table entry parameters then the
+ // content represents a fragment of the value of the recently
+ // created parameter
+
+ if (iXMLContentState == EInParam)
+ {
+ TBuf<MAX_BUFFER_LEN> temp;
+ temp.Copy(aContent);
+ iCurrentParameterValue.Append(temp);
+ }
+ }
+
+void CXMLContentHandler::OnProcessingInstructionL(const TDesC8&, const TDesC8&, TInt)
+ {
+ }
+
+void CXMLContentHandler::OnError(TInt aError)
+ {
+ gMsg->Msg(_L("ERR: Error parsing xml, err=%d"), aError);
+ iError = aError;
+ }
+
+TAny* CXMLContentHandler::GetExtendedInterface(const TInt32)
+ {
+ return NULL;
+ }
+
+void CXMLContentHandler::OnStartPrefixMappingL(const RString&, const RString&, TInt)
+ {
+ iNumPrefixMappings++;
+ }
+
+void CXMLContentHandler::OnEndPrefixMappingL(const RString&, TInt)
+ {
+ iNumPrefixUnmappings++;
+ }
+
+void CXMLContentHandler::OnIgnorableWhiteSpaceL(const TDesC8&, TInt)
+ {
+ }
+
+void CXMLContentHandler::OnSkippedEntityL(const RString&, TInt)
+ {
+ iNumSkippedEntities++;
+ }
+
+void CXMLContentHandler::OnExtensionL(const RString&, TInt, TInt)
+ {
+ }
+
+// Set the IDs for all table entries
+void CXMLContentHandler::SetTableIDs()
+ {
+ TInt iEntry;
+ TInt entryId = 1;
+
+ for (iEntry = 1; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
+ {
+ CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
+ const TBuf<MAX_BUFFER_LEN>& tableName = entry->GetTableName();
+ const TBuf<MAX_BUFFER_LEN>& tableNamePre = iXmlDb->GetTableEntry(iEntry-1)->GetTableName();
+
+ if(tableName.Compare(tableNamePre) == 0)
+ {
+ entryId++;
+ }
+ else
+ {
+ entryId = 1;
+ }
+
+ entry->SetEntryId(entryId);
+ }
+ }
+
+// Some table entries in CommDB do not have a "Name" parameter although
+// in the XML format all table entries must have such a parameter in order
+// to allow table entry referencing. The following loop removes the
+// "Name" parameter from these table entries
+void CXMLContentHandler::RemoveNameParams()
+ {
+ for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
+ {
+ CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
+ const TBuf<MAX_BUFFER_LEN>& tableName = entry->GetTableName();
+
+ for(TInt i = 0; i < numNoNameTables; i++)
+ {
+ if(tableName.Compare(TPtrC(noNameTables[i])) == 0)
+ {
+ TInt numParams = entry->GetNumberParameters();
+
+ // Loop through all the parameters of the current table entry
+ for(TInt iParam = 0; iParam < numParams; iParam++)
+ {
+ const TBuf<MAX_BUFFER_LEN>& paramName = entry->GetParameterName(iParam);
+
+ // Check if this parameter needs modification.
+ if(paramName.Compare(_L("Name")) == 0)
+ {
+ entry->RemoveParameter(iParam);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This function sets the <TableName>.<RecordID> linking in the
+ * case of a linked record in the XML file. So from this point the
+ * processing of the linked record can continue like in the case of
+ * regular cfg files.
+ */
+void CXMLContentHandler::SetCfgLinkingFromXMLFile(const TDesC& aRefTable,
+ const TInt aParamIndex,
+ CXMLTableEntry* aEntry)
+ {
+ TBool finished = EFalse;
+
+ for (TInt i = 0; (!finished) && (i < LinkedRecordTableNum); ++i)
+ {
+ TPtrC linkedRecordTableName(LinkedRecordTableNames[i]);
+
+ if ( linkedRecordTableName == aEntry->GetTableName() )
+ {
+ /**
+ OK, got the table name index. Based on this let's check
+ the name of the linked record...
+ 1 loop for the paramName array in the entry, the other is for the LinkRecordsArray[i]
+ */
+
+ for (TInt j = 0; (!finished) && ((TPtrC(LinkRecordsArray[i][j])) != TPtrC(NO_MORE_RECORDS)); ++j)
+ {
+ TPtrC linkedRecordFromArray(LinkRecordsArray[i][j]);
+
+ if ( linkedRecordFromArray == aEntry->GetParameterName(aParamIndex) )
+ /**
+ * YESSSSS, we have found a linked record. Currently it contains only the
+ * recordID of the referenced record. This should be changed to
+ * Link.tableName.recordID which is in our case the
+ * Link.<aRefTable>.<current recordID>
+ */
+ {
+ TBuf<MAX_BUFFER_LEN> buf;
+ /**
+ * It would be simpler if the Append(TDesc16) would return with a
+ * 'this' reference...
+ */
+ buf.Append(aRefTable);
+ buf.Append(TPtrC(_S(".")));
+ buf.Append(aEntry->GetParameterValue(aParamIndex));
+ aEntry->SetParameterValue(aParamIndex, buf);
+
+ finished = ETrue;
+ }
+ }
+ }
+ }
+ }
+
+/**
+ * This funciton is called if the record referencing from the XML db is not
+ * successful. In this case we try to relove the references from the existing
+ * database.
+ * DEF103749
+ */
+TBool CXMLContentHandler::ResolveRefsFromDbL(CXMLTableEntry* entry,
+ const TInt paramIndex,
+ const TPtrC& refEntryName,
+ const TPtrC& refEntryTable,
+ const TPtrC& orgEntryTable)
+ {
+ TBool retCode = EFalse;
+
+ TMDBElementId elemendID;
+
+ elemendID = iTableNameIDpairs->FindL(refEntryTable);
+
+ //read all of the records form a given table (entry->GetTableName)
+ CMDBRecordSetBase* recordFromDb = new(ELeave) CMDBRecordSetBase(elemendID);
+ CleanupStack::PushL(recordFromDb);
+
+ recordFromDb->LoadL(*iCmdbSession);
+
+ for (TInt i = 0; (!retCode) && (i<recordFromDb->iRecords.Count()); ++i)
+ {
+ if ( CXMLTableEntry::EResolve_XML_Ref == entry->GetLinkType(paramIndex) )
+ //The linking is tableName.RecordName
+ {
+ CMDBField<TDesC> *afn = NULL;
+ TInt temp = 0;
+ CMDBElement* element = recordFromDb->iRecords[i]->GetFieldByNameL(_L("Name"), temp );
+
+ afn = static_cast<CMDBField<TDesC> *>(element);
+
+ TPtrC name(*afn);
+ if (name == refEntryName)
+ //OK, found the refenced record in the db.
+ {
+ TInt recId = recordFromDb->iRecords[i]->RecordId();
+
+ TBuf<MAX_BUFFER_LEN> buf;
+ buf.Format(_L("%D"), recId);
+ entry->SetParameterValue(paramIndex,buf);
+
+ SetCfgLinkingFromXMLFile(orgEntryTable, paramIndex, entry);
+
+ retCode = ETrue;
+ }
+ }
+ else
+ //The linking is tableName.recordID
+ {
+ if ( recordFromDb->iRecords[i]->RecordId() == entry->GetRecordID() )
+ //OK, found the referenced record in the DB.
+ {
+ if ( entry->GetParameterName(paramIndex) == TPtrC(_S("IAPService")) ||
+ entry->GetParameterName(paramIndex) == TPtrC(_S("IAPBearer")) )
+ {
+ TBuf<MAX_BUFFER_LEN> buf;
+ buf.Format(_L("%D"), recordFromDb->iRecords[i]->RecordId());
+
+ entry->SetParameterValue(paramIndex,buf);
+ }
+
+ retCode = ETrue;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(recordFromDb);
+
+ return retCode;
+ }
+
+
+/**
+This function fills up the HashMap, which is used to resolve refences
+from the existing databse.
+*/
+void CXMLContentHandler::FillUpHashMapL(RHashMap<TPtrC, TMDBElementId>& aHashMap)
+ {
+ for (TInt i = 0; i < KPairNumber; ++i)
+ {
+ //Temporary can be used as the parameters (1st param) because RHashMap copies the elements
+ aHashMap.InsertL(TPtrC(tableNamesForPairing[i]), tmdbElementsForPairing[i]);
+ }
+ }
+
+// Resolve the table entry references specified in the XML configuration file
+TBool CXMLContentHandler::ResolveTableEntryReferences(CXMLTableEntry* entry,
+ const TInt paramIndex,
+ const TBuf<MAX_BUFFER_LEN>& refEntryName,
+ const TBuf<MAX_BUFFER_LEN>& refEntryTable,
+ const TBuf<MAX_BUFFER_LEN>& orgEntryTable)
+ {
+ // If the name of the referenced table entry is "-1"
+ // i.e. it does not exist, then the ID is set to "0"
+ if(refEntryName.Compare(_L("-1")) == 0)
+ {
+ if(entry->GetOperation().Compare(_L("template")) == 0)
+ {
+ entry->SetParameterValue(paramIndex,_L("0"));
+ return ETrue;
+ }
+ else
+ {
+ gMsg->Msg(_L("Cannot resolve table entry reference : [%S.%S]"), &refEntryTable, &refEntryName);
+ gMsg->Msg(_L("CED terminates without generating a CommDB database"));
+ return EFalse;
+ }
+ }
+
+ if ( CXMLTableEntry::ESkip_XML__Ref == entry->GetLinkType(paramIndex) )
+ /**
+ We have a link with tablename.-1 referencing. Skip it...
+ */
+ {
+ return ETrue;
+ }
+
+ // Find the ID of the table entry referenced
+ for (TInt k = 0; k < iXmlDb->GetNumberTableEntries(); k++)
+ {
+ CXMLTableEntry* lookEntry = iXmlDb->GetTableEntry(k);
+
+ // Look for table entries which belong to the table
+ // we are looking for
+ if(lookEntry->GetTableName().Compare(refEntryTable) == 0)
+ {
+ if (CXMLTableEntry::EResolve_XML_Ref == entry->GetLinkType(paramIndex))
+ /**
+ The linking is by record name...
+ */
+ {
+ for(TInt m = 0; m < lookEntry->GetNumberParameters(); m++)
+ {
+ const TBuf<MAX_BUFFER_LEN>& param = lookEntry->GetParameterName(m);
+ if(param.Compare(_L("Name")) == 0)
+ {
+ const TBuf<MAX_BUFFER_LEN>& name = lookEntry->GetParameterValue(m);
+ if(name.Compare(refEntryName) == 0)
+ {
+ TBuf<MAX_BUFFER_LEN> buf;
+ buf.Format(_L("%D"), lookEntry->GetRecordID());
+
+ entry->SetParameterValue(paramIndex,buf);
+
+ SetCfgLinkingFromXMLFile(orgEntryTable, paramIndex, entry);
+
+ return ETrue;
+ }
+
+ break;
+ }
+ }
+ }
+ else
+ /**
+ The linking is by recordID...
+ */
+ {
+ TLex16 conv(refEntryName);
+ TInt recId = 0;
+ TInt err = conv.Val(recId);
+
+ if (err == KErrNone && recId == lookEntry->GetRecordID())
+ //We have found the referenced record in the XMLDB
+ {
+ if ( entry->GetParameterName(paramIndex) == TPtrC(_S("IAPService")) ||
+ entry->GetParameterName(paramIndex) == TPtrC(_S("IAPBearer")) )
+ {
+ TBuf<MAX_BUFFER_LEN> buf;
+ buf.Format(_L("%D"), lookEntry->GetRecordID());
+
+ entry->SetParameterValue(paramIndex,buf);
+ }
+
+ return ETrue;
+ }
+ }
+ }
+ }
+
+ // If we reach this point then the ID cannot be resolved. In this case
+ // we have the following options:
+ //
+ // 1. If the table entry currently processing is a template then this
+ // is expected.
+ //
+ // 2. If the table entry currently processing is not a template then
+ // the program terminates if CED is running with the "-F" flag. Else
+ // we set the ID equal to the refered table entry name converted to an
+ // integer
+
+ if (iForceXMLProcessing)
+ {
+ if (entry->GetOperation().Compare(_L("template")) == 0)
+ {
+ TLex16 conv(refEntryName);
+ TInt id = 0;
+ TInt err = conv.Val(id);
+
+ if(err == KErrNone)
+ {
+ TBuf<MAX_BUFFER_LEN> buf;
+ buf.Format(_L("%D"),++id);
+ entry->SetParameterValue(paramIndex,buf);
+ }
+
+ return ETrue;
+ }
+ else
+ {
+ TBool ret = EFalse;
+ TRAPD(leavingError, ret = ResolveRefsFromDbL(entry, paramIndex, refEntryName, refEntryTable, orgEntryTable));
+
+ if (!leavingError)
+ {
+ if (!ret)
+ {
+ gMsg->Msg(_L("Cannot resolve table entry reference from the DB: [%S.%S]"), &refEntryTable, &refEntryName);
+ gMsg->Msg(_L("CED terminates without generating a CommDB database"));
+ }
+ return ret;
+ }
+ else
+ {
+ gMsg->Msg(_L("Cannot resolve table entry reference from the DB: [%S.%S]"), &refEntryTable, &refEntryName);
+ gMsg->Msg(_L("CED terminates without generating a CommDB database"));
+
+ return EFalse;
+ }
+
+ }
+ }
+ else
+ {
+ gMsg->Msg(_L("Cannot resolve table entry reference : [%S.%S]"), &refEntryTable, &refEntryName);
+ gMsg->Msg(_L("CED terminates without generating a CommDB database"));
+ return EFalse;
+ }
+ }
+
+/**
+ * Map the recordIDs from the database into the data structure in which the
+ * the xml elements are stored. It is needed for the proper linking.
+ * DEF103749
+ */
+void CXMLContentHandler::SetRecordIDsL()
+ {
+ //RAII
+ TMDBElementId elemendID = 0;
+
+ TInt entryNum = 0,
+ tempEntryNum = 0,
+ baseRecordID = 0;
+
+ TBool entryEnd = EFalse;
+
+ CXMLTableEntry* entry = NULL,
+ * tempEntry = NULL;
+
+ CMDBRecordBase* recordFromDb = NULL;
+
+ while (entryNum < iXmlDb->GetNumberTableEntries())
+ {
+ entry = iXmlDb->GetTableEntry(entryNum);
+
+ if ( TPtrC(_S("template")) == entry->GetOperation() )
+ /**
+ * Handling templates is a bit trickier than simple addings...
+ *
+ * Note: it's not handled here when 1 table contains more tham 1 template records in the
+ * config file...
+ * Should CED be prepared for this????????????????????????
+ */
+ {
+ if (isInAppendMode)
+ {
+ elemendID = iTableNameIDpairs->FindL(entry->GetTableName());
+
+ // Enable ECDHidden on session to be able to read the template records
+ iCmdbSession->SetAttributeMask(ECDHidden);
+
+
+ recordFromDb = new(ELeave) CMDBRecordBase(elemendID);
+ CleanupStack::PushL(recordFromDb);
+
+ recordFromDb->SetRecordId(KCDDefaultRecord);
+
+ /**
+ * This leave has to be trapped becasuse CED should be prepared for the
+ * cases where a template record is already existing in the given
+ * table.
+ */
+ TRAPD(leavingError, recordFromDb->LoadL(*iCmdbSession));
+
+ if (!leavingError)
+ /**
+ * The LoadL didn't leave, which means that we have already a template
+ * record for the given table in the database. The record read from the xml
+ * file cannot be appended.
+ */
+ {
+ gMsg->Msg(_L("Warning - Duplicate TEMPLATE records for the table: [%S]"),&entry->GetTableName());
+ gMsg->Msg(_L("Skipping it..."));
+
+ entry->SetDeleteFlag(ETrue);
+ }
+ else
+ /**
+ * The given table doesn't have yet a template record so the one which was read from
+ * the xml file can be appended.
+ */
+ {
+ entry->SetRecordID(0);
+ }
+
+ CleanupStack::PopAndDestroy(recordFromDb);
+ recordFromDb = NULL;
+ }
+ else
+ /**
+ * Simply give the record number 0 for the template record as we are not in append mode.
+ */
+ {
+ entry->SetRecordID(0);
+ }
+
+
+ // Disable ECDNoWriteButDelete on session
+ iCmdbSession->ClearAttributeMask(ECDHidden);
+
+ ++entryNum;
+ }
+ else
+ /**
+ * Simple addings...
+ */
+ {
+ if (isInAppendMode)
+ {
+ TRAPD(leavingError, elemendID = iTableNameIDpairs->FindL(entry->GetTableName()));
+
+ if (!leavingError)
+ {
+ CMDBRecordSetBase* recordSetFromDb = new(ELeave) CMDBRecordSetBase(elemendID);
+ CleanupStack::PushL(recordSetFromDb);
+
+ recordSetFromDb->LoadL(*iCmdbSession);
+
+ TInt recIdMax = 0;
+
+ for (TInt i = 0; i<recordSetFromDb->iRecords.Count(); ++i)
+ {
+ recordFromDb = recordSetFromDb->iRecords[i];
+
+ if (recordFromDb->RecordId() > recIdMax)
+ recIdMax = recordFromDb->RecordId();
+ }
+
+ baseRecordID = recIdMax+1;
+
+ CleanupStack::PopAndDestroy(recordSetFromDb);
+ }
+ else
+ {
+ gMsg->Msg(_L("Warning - cannot append records to the table: [%S]"),&entry->GetTableName());
+ gMsg->Msg(_L("Skipping it..."));
+
+ entry->SetDeleteFlag(ETrue);
+ }
+ }
+ else
+ {
+ baseRecordID = 1;
+ }
+
+ entryEnd = EFalse;
+
+ for (tempEntryNum = entryNum;
+ (!entryEnd) && (tempEntryNum < iXmlDb->GetNumberTableEntries());
+ ++tempEntryNum)
+ {
+ tempEntry = iXmlDb->GetTableEntry(tempEntryNum);
+
+ if (entry->GetTableName() != tempEntry->GetTableName())
+ {
+ entryEnd = ETrue;
+ break;
+ }
+ else
+ {
+ tempEntry->SetRecordID(baseRecordID++);
+ }
+
+ entryNum = entryNum+(tempEntryNum-entryNum)+1;
+
+ }
+ }
+ }
+ }
+
+
+// CommDB requires the conversion of the references to table entries using the qualified
+// name scheme of the XML configuration file to one which employs a table entry ID and
+// an additional parameter which indicates the name of the table the entry belongs to
+TBool CXMLContentHandler::ModifyTableEntryReferencesL()
+ {
+ // Set the IDs for all table entries
+ SetTableIDs();
+
+ TRAPD(leavingError, SetRecordIDsL());
+
+ if (KErrNone != leavingError)
+ return EFalse;
+
+ //if some entrys have the deleted flag true they are deleted here...
+ iXmlDb->CheckDeletedElems();
+
+ // Modify the table references
+
+ for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
+ {
+ CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
+
+ // Loop through all the table parameters to modify
+ for(TInt iMod = 0; iMod < numMods; iMod++)
+ {
+ const TBuf<MAX_BUFFER_LEN>& modName = modParam[iMod];
+
+ // Look for table entries which belong to the table
+ // we need to modify
+
+ if(entry->GetTableName().Compare(TPtrC(modTable[iMod])) == 0)
+ {
+ // Loop through all the parameters of the current table entry
+ for(TInt iParam = 0; iParam < entry->GetNumberParameters(); iParam++)
+ {
+ const TBuf<MAX_BUFFER_LEN>& paramName = entry->GetParameterName(iParam);
+
+ // Check if this parameter needs modification.
+ if(paramName.Compare(modName) == 0)
+ {
+ // Extract the value of the name of the table the table entry
+ // reference belongs to as well as the name of the table entry
+ const TBuf<MAX_BUFFER_LEN>& paramValue = entry->GetParameterValue(iParam);
+
+ gMsg->Msg(_L("Modifying Parameter : [%S] = [%S]"),¶mName,¶mValue);
+
+ TBuf<MAX_BUFFER_LEN> refEntryTable;
+ TInt k, m;
+
+ for(k = 0; k < paramValue.Length(); k++)
+ {
+ TChar c = paramValue[k];
+ if(c == TChar('.')) break;
+ refEntryTable.Append(c);
+ }
+
+ TBuf<MAX_BUFFER_LEN> orgEntryTable;
+ orgEntryTable.Copy(refEntryTable);
+ refEntryTable.Append(_L("Table"));
+
+ gMsg->Msg(_L(" Referenced Table Name = [%S]"),&refEntryTable);
+
+ if (!IsTableKnown(orgEntryTable))
+ {
+ //The referenced table is not supported anymore. Skip it...
+ gMsg->Msg(_L("ERR: Referenced Table Name = [%S] is not known by CED. Skipping it..."),&refEntryTable);
+ }
+ else
+ {
+ TBuf<MAX_BUFFER_LEN> refEntryName;
+ for(m = k+1; m < paramValue.Length(); m++)
+ refEntryName.Append(paramValue[m]);
+
+ gMsg->Msg(_L(" Referenced Table Entry Name = [%S]"),&refEntryName);
+
+ // Rename the modified parameter
+ entry->RenameParameter(iParam,newModParam[iMod]);
+
+ /**
+ Setting the linking type - if any
+ */
+ TLex16 conv(refEntryName);
+ TInt recId = 0;
+ TInt err = conv.Val(recId);
+
+ if(err == KErrNone)
+ /**
+ OK, the conversion is successful. Let's see whether is it a non relevant link
+ (tableName.-1) or a relevant one...
+ */
+ {
+ if (-1 == recId)
+ /**
+ The link can be skipped...
+ */
+ {
+ entry->ModifyLinkType(iParam, CXMLTableEntry::ESkip_XML__Ref);
+ }
+ else
+ /**
+ The reference is by record id...
+ */
+ {
+ entry->ModifyLinkType(iParam, CXMLTableEntry::ERecord_ID_Reference);
+ }
+ }
+ else
+ /**
+ The conversion wasn't successful, so the given reference is
+ not record ID.
+ */
+ {
+ entry->ModifyLinkType(iParam, CXMLTableEntry::EResolve_XML_Ref);
+ }
+
+ // If the name of the table must be specified then add
+ // an additional parameter for that purpose
+ if(TPtrC(typeParam[iMod]).Compare(_L("")) != 0)
+ {
+ if(orgEntryTable.Compare(_L("Proxy")) == 0)
+ orgEntryTable.Copy(_L("Proxies"));
+ else if(orgEntryTable.Compare(_L("BTDevice")) == 0)
+ orgEntryTable.Append(_L("Table"));
+ else if(orgEntryTable.Compare(_L("BTDefault")) == 0)
+ orgEntryTable.Append(_L("Table"));
+ else if(orgEntryTable.Compare(_L("BTSecurity")) == 0)
+ orgEntryTable.Append(_L("Table"));
+ else if(orgEntryTable.Compare(_L("BTPersist")) == 0)
+ orgEntryTable.Append(_L("Table"));
+ else if(orgEntryTable.Compare(_L("SecureSocket")) == 0)
+ orgEntryTable.Append(_L("Table"));
+ else if(orgEntryTable.Compare(_L("UmtsR99QoSAndOn")) == 0)
+ orgEntryTable.Append(_L("Table"));
+
+ entry->AddParameterL(typeParam[iMod],orgEntryTable);
+ }
+
+ // Resolve the table entry references
+ TBool bResolved = ResolveTableEntryReferences(entry,iParam,refEntryName,refEntryTable, orgEntryTable);
+
+ if(!bResolved)
+ {
+ return EFalse;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Some table entries in CommDB do not have a "Name" parameter although
+ // in the XML format all table entries must have such a parameter in order
+ // to allow table entry referencing. The following loop removes the
+ // "Name" parameter from these table entries
+ RemoveNameParams();
+
+ return ETrue;
+ }
+
+// Dump the contents of the table entries on the log file
+void CXMLContentHandler::LogTableEntries()
+ {
+ gMsg->Msg(_L("Log Dump of CommDB Table Contents"));
+
+ for (TInt iEntry = 0; iEntry < iXmlDb->GetNumberTableEntries(); iEntry++)
+ {
+ CXMLTableEntry* entry = iXmlDb->GetTableEntry(iEntry);
+
+ gMsg->Msg(_L("Table : [%S]"),&entry->GetTableName());
+ gMsg->Msg(_L("Table Entry ID = [%D]"),entry->GetEntryId());
+
+ for(TInt iParam = 0; iParam < entry->GetNumberParameters(); iParam++)
+ {
+ gMsg->Msg(_L(" [%S] = [%S]"),&entry->GetParameterName(iParam),&entry->GetParameterValue(iParam));
+ }
+ }
+ }
+
+bool CXMLContentHandler::IsTableKnown(const TDesC& aRefTable)
+ {
+ TInt i = 0;
+ TPtrC actTableName = xmlTableArray[i];
+
+ while(actTableName.Compare(TPtrC(NO_MORE_RECORDS)) != 0 &&
+ actTableName.Compare(aRefTable) != 0)
+ {
+ actTableName.Set(TPtrC(xmlTableArray[++i]));
+ }
+
+ if (aRefTable.Compare(actTableName) == 0)
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+//----------------- CXMLTableEntry ----------------
+
+
+// Constructor for the CXMLTableEntry class
+CXMLTableEntry::CXMLTableEntry()
+: entryId(1)
+, iRecordID(0)
+, iDeleteFlag(EFalse)
+ {
+ __DECLARE_NAME(_S("CXMLTableEntry"));
+ }
+
+// Destructor for the CXMLTableEntry class
+CXMLTableEntry::~CXMLTableEntry()
+ {
+ paramName.ResetAndDestroy();
+ paramValue.ResetAndDestroy();
+
+ iLinkType.Close();
+ }
+
+CXMLTableEntry* CXMLTableEntry::NewL(const TDesC& aTableName)
+ {
+ CXMLTableEntry* p = new(ELeave) CXMLTableEntry;
+ CleanupStack::PushL(p);
+ p->ConstructL(aTableName);
+ CleanupStack::Pop(p);
+ return p;
+ }
+
+void CXMLTableEntry::ConstructL(const TDesC& aTableName)
+ {
+ tableName.Copy(aTableName);
+ }
+
+// Add a new pair of paramater name and value in this table entry
+void CXMLTableEntry::AddParameterL(const TBuf<MAX_BUFFER_LEN>& aParamName,
+ const TBuf<MAX_BUFFER_LEN>& aParamValue)
+ {
+ TBuf<MAX_BUFFER_LEN>* name = new(ELeave) TBuf<MAX_BUFFER_LEN>;
+ name->Copy(aParamName);
+ paramName.Append(name);
+
+ TBuf<MAX_BUFFER_LEN>* value = new(ELeave) TBuf<MAX_BUFFER_LEN>;
+ value->Copy(aParamValue);
+ paramValue.Append(value);
+ }
+
+// Remove a parameter from the list
+void CXMLTableEntry::RemoveParameter(const TInt aIndex)
+ {
+ delete paramName[aIndex];
+ paramName.Remove(aIndex);
+ delete paramValue[aIndex];
+ paramValue.Remove(aIndex);
+ }
+
+// Set the value of a parameter given its index
+void CXMLTableEntry::SetParameterValue(const TInt aIndex,
+ const TBuf<MAX_BUFFER_LEN>& aParamValue)
+ {
+ paramValue[aIndex]->Copy(aParamValue);
+ }
+
+// Rename a table entry parameter
+void CXMLTableEntry::RenameParameter(const TInt aIndex, const TBuf<MAX_BUFFER_LEN>& aNewName)
+ {
+ paramName[aIndex]->Copy(aNewName);
+ }
+
+
+
+
+//------------------ CXMLDatabase --------------------
+
+
+
+// Constructor for the CXMLDatabase class
+CXMLDatabase::CXMLDatabase()
+ {
+ __DECLARE_NAME(_S("CXMLDatabase"));
+ }
+
+// Destructor for the CXMLDatabase class
+CXMLDatabase::~CXMLDatabase()
+ {
+ tableEntries.ResetAndDestroy();
+ }
+
+CXMLDatabase* CXMLDatabase::NewL()
+ {
+ CXMLDatabase* p = new(ELeave) CXMLDatabase;
+ return p;
+ }
+
+// Add a table entry to the database given the pointer
+void CXMLDatabase::AddTableEntry(CXMLTableEntry* aEntry)
+ {
+ if(aEntry != NULL)
+ {
+ tableEntries.Append(aEntry);
+ }
+ }
+
+// Get a table entry from the database given its index which represents
+// its location in the database
+CXMLTableEntry* CXMLDatabase::GetTableEntry(const TInt aIndex)
+ {
+ if(aIndex >= 0 && aIndex < tableEntries.Count())
+ {
+ return tableEntries[aIndex];
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+// Get the total number of table entries currently in the database
+TInt CXMLDatabase::GetNumberTableEntries() const
+ {
+ return tableEntries.Count();
+ }
+
+// Get the last table entry added to the database
+CXMLTableEntry* CXMLDatabase::GetLastTableEntry()
+ {
+ TInt index = tableEntries.Count();
+ if(index == 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ return tableEntries[index-1];
+ }
+ }
+
+void CXMLDatabase::CheckDeletedElems()
+ {
+ TInt i = 0;
+
+ while (i < tableEntries.Count())
+ {
+ if (tableEntries[i]->GetDeleteFlag())
+ {
+ delete tableEntries[i];
+ tableEntries.Remove(i);
+ }
+ else
+ {
+ ++i;
+ }
+ }
+ }
+
+
+