| /******************************************************************************* | |
| * Copyright (c) 2012 - 2014 AIT, ACIN, fortiss GmbH | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Public License 2.0 which is available at | |
| * http://www.eclipse.org/legal/epl-2.0. | |
| * | |
| * SPDX-License-Identifier: EPL-2.0 | |
| * | |
| * Contributors: | |
| * Filip Andren, Alois Zoitl - initial API and implementation and/or initial documentation | |
| *******************************************************************************/ | |
| #include "EplXmlReader.h" | |
| #include <string_utils.h> | |
| #include <cstdlib> | |
| #include <iostream> | |
| #include <fstream> | |
| #include <string.h> | |
| using namespace std; | |
| #include <tinyxml.h> | |
| CEplXmlReader::CEplXmlReader(CProcessImageMatrix* pa_pIn, CProcessImageMatrix* pa_pOut){ | |
| m_pProcImageIn = pa_pIn; | |
| m_pProcImageOut = pa_pOut; | |
| } | |
| CEplXmlReader::~CEplXmlReader(){ | |
| } | |
| void CEplXmlReader::setProcessImageIn(CProcessImageMatrix* pa_pIn){ | |
| m_pProcImageIn = pa_pIn; | |
| } | |
| void CEplXmlReader::setProcessImageOut(CProcessImageMatrix* pa_pOut){ | |
| m_pProcImageOut = pa_pOut; | |
| } | |
| void CEplXmlReader::readXmlFile(const char* pa_pchFileName){ | |
| TiXmlDocument xmlDoc(pa_pchFileName); | |
| if(xmlDoc.LoadFile()){ | |
| TiXmlNode *appProcess = xmlDoc.FirstChild("ApplicationProcess"); | |
| TiXmlNode *processImageIn; | |
| for(TiXmlNode *processImage = appProcess->ToElement()->FirstChild("ProcessImage"); processImage != NULL; processImage = processImage->NextSibling("ProcessImage")){ | |
| if(strcmp(processImage->ToElement()->Attribute("type"), "output") == 0){ | |
| createProcImageOut(processImage); | |
| } | |
| else if(strcmp(processImage->ToElement()->Attribute("type"), "input") == 0){ | |
| processImageIn = processImage; | |
| } | |
| } | |
| createProcImageIn(processImageIn); | |
| } | |
| else{ | |
| cout << "ERROR: Could not open XML file" << endl; | |
| } | |
| } | |
| void CEplXmlReader::createProcImageOut(TiXmlNode* pa_pProcessImage){ | |
| int currentCnId = -1; | |
| int currentModuleNr = -1; | |
| char currentModuleId[256]; | |
| int currentIoNr = -1; | |
| TiXmlNode *channel; | |
| for(channel = pa_pProcessImage->FirstChild("Channel"); channel != NULL; channel = channel->NextSibling("Channel")){ | |
| // New IO | |
| currentIoNr++; | |
| // Get "Name" attribute | |
| const char *ioName = channel->ToElement()->Attribute("Name"); | |
| char *nameStr = new char[strlen(ioName) + 1]; | |
| strcpy(nameStr, ioName); | |
| // Get CN ID | |
| char* pch = strtok(nameStr, ".CN"); | |
| int cnId = forte::core::util::strtol(pch,0,10); | |
| // Get module ID | |
| char* modId = strtok(NULL, "."); | |
| // Get dataSize | |
| const char *temp = channel->ToElement()->Attribute("dataSize"); | |
| int dSize = forte::core::util::strtoul(temp,0,10); | |
| // Get PIOffset | |
| temp = channel->ToElement()->Attribute("PIOffset"); | |
| long piOffset = forte::core::util::strtol(temp, NULL, 16); | |
| // Get BitOffset | |
| long bitOffset = 0; | |
| temp = channel->ToElement()->Attribute("BitOffset"); | |
| if(temp != NULL){ | |
| bitOffset = forte::core::util::strtol(temp, NULL, 16); | |
| } | |
| // Check CN id, module number and add new IO | |
| if(cnId != currentCnId){ // New CN | |
| currentCnId = cnId; | |
| currentModuleNr = 0; | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListOut.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageOut->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else if(m_oModuleListOut.moduleNameExist(ioName)){ // IO name exist => this must be a new module with same brand as another | |
| currentModuleNr++; | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListOut.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageOut->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else if(strcmp(modId, currentModuleId) == 0){ // same module ID as IO before => must be same module | |
| m_pProcImageOut->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else{ // new module ID => new module | |
| currentModuleNr++; | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListOut.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageOut->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| cout << "<< " << currentCnId << ", " << currentModuleNr << ", " << ioName << ", " << currentIoNr << ", " << dSize << ", " << piOffset << ", " << bitOffset << endl; | |
| delete[] nameStr; | |
| } | |
| } | |
| void CEplXmlReader::createProcImageIn(TiXmlNode *pa_pProcessImage){ | |
| int currentCnId = -1; | |
| int currentModuleNr = -1; | |
| char currentModuleId[256]; | |
| int currentIoNr = -1; | |
| TiXmlNode *channel; | |
| for(channel = pa_pProcessImage->FirstChild("Channel"); channel != NULL; channel = channel->NextSibling("Channel")){ | |
| // New IO | |
| currentIoNr++; | |
| // Get "Name" attribute | |
| const char *ioName = channel->ToElement()->Attribute("Name"); | |
| char *nameStr = new char[strlen(ioName) + 1]; | |
| strcpy(nameStr, ioName); | |
| // Get CN ID | |
| char* pch = strtok(nameStr, ".CN"); | |
| int cnId = forte::core::util::strtoul(pch,0,10); | |
| // Get module ID | |
| char* modId = strtok(NULL, "."); | |
| // Get dataSize | |
| const char *temp = channel->ToElement()->Attribute("dataSize"); | |
| int dSize = forte::core::util::strtoul(temp,0,10); | |
| // Get PIOffset | |
| temp = channel->ToElement()->Attribute("PIOffset"); | |
| long piOffset = forte::core::util::strtol(temp, NULL, 16); | |
| // Get BitOffset | |
| long bitOffset = 0; | |
| temp = channel->ToElement()->Attribute("BitOffset"); | |
| if(temp != NULL){ | |
| bitOffset = forte::core::util::strtol(temp, NULL, 16); | |
| } | |
| // Check CN id, module number and add new IO | |
| if(cnId != currentCnId){ // New CN | |
| currentCnId = cnId; | |
| currentModuleNr = getModuleNr(ioName); | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListIn.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageIn->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else if(m_oModuleListIn.moduleNameExist(ioName)){ // IO name exist => this must be a new module with same brand as another | |
| currentModuleNr = getModuleNr(ioName); | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListIn.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageIn->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else if(strcmp(modId, currentModuleId) == 0){ // same module ID as IO before => must be same module | |
| m_pProcImageIn->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| else{ // new module ID => new module | |
| currentModuleNr = getModuleNr(ioName); | |
| strcpy(currentModuleId, modId); | |
| currentIoNr = 0; | |
| m_oModuleListIn.addEntry(ioName, piOffset, bitOffset, currentModuleNr); | |
| m_pProcImageIn->addEntry(cnId, currentModuleNr, currentIoNr, dSize, piOffset, bitOffset); | |
| } | |
| cout << ">> " << currentCnId << ", " << currentModuleNr << ", " << ioName << ", " << currentIoNr << ", " << dSize << ", " << piOffset << ", " << bitOffset << endl; | |
| delete[] nameStr; | |
| } | |
| } | |
| int CEplXmlReader::getModuleNr(const char* pa_pchIoId){ | |
| char localCopy[256]; | |
| strcpy(localCopy, pa_pchIoId); | |
| char dest[256]; | |
| char* pch = strtok(localCopy, "."); | |
| strcpy(dest, pch); | |
| strcat(dest, "."); | |
| pch = strtok(NULL, "."); | |
| strcat(dest, pch); | |
| int occurences = m_oModuleListIn.getNrOfModules(dest); | |
| int modNr = m_oModuleListOut.getModuleNr(dest, occurences + 1); | |
| if(modNr == -1) { | |
| cout << "ShouldNotHappenError" << endl; | |
| } | |
| return modNr; | |
| } |