blob: fc46fe38f3f7eab7abee7e3606da92feb3a14fa5 [file] [log] [blame]
/*******************************************************************************
* 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;
}