From 9f053e53e3275675e575683bda492b61b20c4797 Mon Sep 17 00:00:00 2001 From: Andrea Zoli <athlonz900@gmail.com> Date: Thu, 19 Feb 2015 22:41:58 +0100 Subject: [PATCH] Fix xml parsing of SDFBlocks. --- src/ConfigurationFile.cpp | 1 - src/Field.cpp | 4 +- src/InputPacketStream.cpp | 1 + src/Packet.cpp | 46 -------- src/PacketStream.cpp | 8 +- src/SDFBlock.cpp | 230 +++++++++++++++++++++----------------- 6 files changed, 134 insertions(+), 156 deletions(-) diff --git a/src/ConfigurationFile.cpp b/src/ConfigurationFile.cpp index 692db65..6ee6872 100644 --- a/src/ConfigurationFile.cpp +++ b/src/ConfigurationFile.cpp @@ -87,7 +87,6 @@ char* ConfigurationFile::getLine() throw(PacketExceptionIO*) char* ConfigurationFile::getLine(const char* s) throw(PacketExceptionIO*) { char* line; - try { line = this->getLine(); diff --git a/src/Field.cpp b/src/Field.cpp index ad9af93..5d5f0c1 100644 --- a/src/Field.cpp +++ b/src/Field.cpp @@ -19,6 +19,8 @@ #include "Field.h" #include "Utility.h" +//#define DEBUG 1 + using namespace PacketLib; static FieldType** filedTypeList = 0; @@ -92,7 +94,7 @@ Field::Field(std::string name, std::string typeStr, std::string dim, std::string type->dimension = atoi(dim.c_str()); type->type = Field::typeStringToEnum[typeStr]; #ifdef DEBUG - std::cout << "Adding field '" << name << "' at index " << i << ", " << type->dimension << " bits type " << typeStr << " (" << type->type << ")" << std::endl; + std::cout << "Adding field '" << name << "', " << type->dimension << " bits type " << typeStr << " (" << type->type << ")" << std::endl; #endif if(prVal.compare("none") != 0) diff --git a/src/InputPacketStream.cpp b/src/InputPacketStream.cpp index cbd202e..fd35c5d 100644 --- a/src/InputPacketStream.cpp +++ b/src/InputPacketStream.cpp @@ -20,6 +20,7 @@ using namespace PacketLib; +#undef DEBUG InputPacketStream::InputPacketStream() : PacketStream() { diff --git a/src/Packet.cpp b/src/Packet.cpp index 33bcd71..1632a85 100644 --- a/src/Packet.cpp +++ b/src/Packet.cpp @@ -64,52 +64,6 @@ Packet::~Packet() delete[] identifiers; } -const std::string fixed32[] = { "uint32", "int32", "float" }; -const std::string fixed64[] = { "uint64", "int64", "double" }; - -void cachePhysicalIndexes(pugi::xml_node node, std::map<pugi::xml_node, int>& physicalIndex) -{ - int index = 0; - for(pugi::xml_node_iterator it=node.begin(); it != node.end(); ++it) - { - if(string(it->name()).compare("field") != 0) - continue; - - physicalIndex[*it] = index; - - // if 32bits fields - string typeStr = it->attribute("type").value(); - bool found = false; - for(unsigned int i=0; i<3; i++) - { - if(typeStr.compare(fixed32[i]) == 0) - { - index+=2; - found = true; - break; - } - } - if(found) - continue; - - // if 64bits fields - for(unsigned int i=0; i<3; i++) - { - if(typeStr.compare(fixed64[i]) == 0) - { - index+=4; - found = true; - break; - } - } - if(found) - continue; - - // else (<= 16bits fields) - index++; - } -} - void Packet::createPacketType(pugi::xml_document& doc, pugi::xml_node hNode, int plPhysicalIndex, int plSize, pugi::xml_node pNode, bool isprefix, word dimprefix, std::map<pugi::xml_node, int>& physicalIndex) { name = pNode.attribute("name").value(); diff --git a/src/PacketStream.cpp b/src/PacketStream.cpp index 89f2b29..d20987d 100644 --- a/src/PacketStream.cpp +++ b/src/PacketStream.cpp @@ -25,10 +25,6 @@ using namespace PacketLib; - - - - PacketStream::PacketStream(string fileNameConfig) { filenameConfig = realpath(fileNameConfig.c_str(), NULL); @@ -158,7 +154,9 @@ void PacketStream::cachePhysicalIndexes(pugi::xml_node node, std::map<pugi::xml_ { if(string(it->name()).compare("field") != 0) continue; - +#ifdef DEBUG + std::cout << "Physical index of " << it->attribute("name").value() << " is " << index << std::endl; +#endif physicalIndex[*it] = index; // if 32bits fields diff --git a/src/SDFBlock.cpp b/src/SDFBlock.cpp index ccde830..eb327b7 100644 --- a/src/SDFBlock.cpp +++ b/src/SDFBlock.cpp @@ -36,11 +36,17 @@ void SDFBlockType::loadType(pugi::xml_node node, const pugi::xml_document& doc, { nblockmax = 0; - const char* popName = node.attribute("name").value(); + std::string tmp; + if(strcmp(node.name(),"sourcedatafield") == 0) + { + tmp = std::string(node.parent().attribute("name").value()) + "_sdf"; + } + else + tmp = node.attribute("name").value(); - int dimline = strlen(popName); - name = (char*) new char[dimline+1]; - strncpy(name, popName, dimline+1); + name = (char*) new char[tmp.size()+1]; + strncpy(name, tmp.c_str(), tmp.size()); + name[tmp.size()] = 0; pugi::xml_node fNode = node.child("field"); if(fNode) @@ -50,115 +56,123 @@ void SDFBlockType::loadType(pugi::xml_node node, const pugi::xml_document& doc, variablePresent = false; pugi::xpath_node_set rbNodeSet = node.select_nodes("rblock"); - if(rbNodeSet.size() == 0) + if(rbNodeSet.size() == 0) + { + numberOfRBlocks = 0; + rblockFilename = 0; + rBlockVariable = 0; + maxNumberOfBlock = 0; + indexOfNBlock = 0; + subFromNBlock = 0; + numberOfBlockFixed = 0; + headerLevelOfNBlockIndex = 0; + operatorType = 0; + + return; + } + variablePresent = true; +#ifdef DEBUG + std::cout << "fixed part: " << variablePresent; + std::cout << " variable part: " << variablePresent << std::endl; +#endif + numberOfRBlocks = rbNodeSet.size(); + if(numberOfRBlocks > 65535) + throw new PacketExceptionFileFormat("Too many number of Rblocks in the packet type."); + rblockFilename = new char*[numberOfRBlocks]; + rBlockVariable = new bool[numberOfRBlocks]; + maxNumberOfBlock = new word[numberOfRBlocks]; + indexOfNBlock = new word[numberOfRBlocks]; + subFromNBlock = new word[numberOfRBlocks]; + numberOfBlockFixed = new bool[numberOfRBlocks]; + headerLevelOfNBlockIndex = new word[numberOfRBlocks]; + operatorType = new byte[numberOfRBlocks]; + + for(int i=0; i < numberOfRBlocks; i++) { - variablePresent = true; - numberOfRBlocks = rbNodeSet.size(); - if(numberOfRBlocks > 65535) - throw new PacketExceptionFileFormat("Too many number of Rblocks in the packet type."); - rblockFilename = new char*[numberOfRBlocks]; - rBlockVariable = new bool[numberOfRBlocks]; - maxNumberOfBlock = new word[numberOfRBlocks]; - indexOfNBlock = new word[numberOfRBlocks]; - subFromNBlock = new word[numberOfRBlocks]; - numberOfBlockFixed = new bool[numberOfRBlocks]; - headerLevelOfNBlockIndex = new word[numberOfRBlocks]; - operatorType = new byte[numberOfRBlocks]; - - for(int i=0; i < numberOfRBlocks; i++) + const pugi::xml_node rbNode = rbNodeSet[i].node(); + pugi::xml_attribute idref = rbNode.attribute("idref"); + if(idref) + rBlockVariable[i] = true; + else + rBlockVariable[i] = false; + + const char* nblocks = rbNode.attribute("maxnumberofblocks").value(); + maxNumberOfBlock[i] = atoi(nblocks); + if(maxNumberOfBlock[i] > 65535) + throw new PacketExceptionFileFormat("Too many number of blocks in the packet type."); + + if(!idref) { - const pugi::xml_node rbNode = rbNodeSet[i].node(); - pugi::xml_attribute idref = rbNode.attribute("idref"); - if(idref) - rBlockVariable[i] = true; - else - rBlockVariable[i] = false; - - const char* nblocks = rbNode.attribute("maxnumberofblocks").value(); - maxNumberOfBlock[i] = atoi(nblocks); - if(maxNumberOfBlock[i] > 65535) - throw new PacketExceptionFileFormat("Too many number of blocks in the packet type."); - - if(!idref) - headerLevelOfNBlockIndex[i] = 0; - else - { - string query = string("//field[@id=\"")+idref.value()+"\"]"; - pugi::xml_node numberofblocksid = doc.select_nodes(query.c_str())[0].node(); - pugi::xml_node nodetmp = rbNode; - unsigned int level = 0; + stringstream ss; + ss << "idref attribute not defined for rblock" << rbNode.attribute("name").value(); + throw new PacketExceptionFileFormat(ss.str().c_str()); + } + + string query = string("//field[@id=\"")+idref.value()+"\"]"; + pugi::xml_node numberofblocksid = doc.select_nodes(query.c_str())[0].node(); + pugi::xml_node nodetmp = rbNode; + unsigned int level = 0; - while(nodetmp.parent() != numberofblocksid.parent()) + while(nodetmp.parent() != numberofblocksid.parent()) + { + // if the parent is a packet means that the id is not in the fixed part of the + // recursive rblocks nor the sourcedatafield. So test the datafieldheader + // and header, otherwise complain. + if(string(nodetmp.parent().name()).compare("packet") == 0) + { + string idparentnodename = numberofblocksid.parent().name(); + if(idparentnodename.compare("datafieldheader") == 0) + { + // we have already add 1 level because nodetmp in this case is + // the sourcedatafield node + } + else if(idparentnodename.compare("header") == 0) { - // if the parent is a packet means that the id is not in the fixed part of the - // recursive rblocks nor the sourcedatafield. So test the datafieldheader - // and header, otherwise complain. - if(string(nodetmp.parent().name()).compare("packet") == 0) - { - string idparentnodename = numberofblocksid.parent().name(); - if(idparentnodename.compare("datafieldheader") == 0) - { - // we have already add 1 level because nodetmp in this case is - // the sourcedatafield node - } - else if(idparentnodename.compare("header") == 0) - { - // we add just one level for the same reason above - level++; - } - else - { - std::stringstream ss; - ss << "Error on id association. Id'" << idref.value() << "' doesn't exists. idref defined by rblock '" << rbNode.attribute("name").value() << "'."; - throw new PacketExceptionFileFormat(ss.str().c_str()); - } - - break; - } + // we add just one level for the same reason above level++; - nodetmp = nodetmp.parent(); } - headerLevelOfNBlockIndex[i] = level; - indexOfNBlock[i] = physicalIndex[numberofblocksid]; // TODO fix this.. - pugi::xml_attribute offsetAttr = numberofblocksid.attribute("numberofblocksoffset"); - const char* offset; - if(offsetAttr) - offset = offsetAttr.value(); else - offset = "0"; - - switch(offset[0]) { - case '/': - operatorType[i] = 1; - subFromNBlock[i] = atoi(offset+1); - break; - case '*': - operatorType[i] = 2; - subFromNBlock[i] = atoi(offset+1); - break; - default: - operatorType[i] = 0; - subFromNBlock[i] = atoi(offset); + std::stringstream ss; + ss << "Error on id association. Id'" << idref.value() << "' doesn't exists. idref defined by rblock '" << rbNode.attribute("name").value() << "'."; + throw new PacketExceptionFileFormat(ss.str().c_str()); } - rblockFilename[i] = (char*) rbNode.attribute("name").value(); + break; } + level++; + nodetmp = nodetmp.parent(); + } + headerLevelOfNBlockIndex[i] = level; + indexOfNBlock[i] = physicalIndex[numberofblocksid]; + pugi::xml_attribute offsetAttr = numberofblocksid.attribute("numberofblocksoffset"); + const char* offset; + if(offsetAttr) + offset = offsetAttr.value(); + else + offset = "0"; - nblockmax += maxNumberOfBlock[i]; + switch(offset[0]) + { + case '/': + operatorType[i] = 1; + subFromNBlock[i] = atoi(offset+1); + break; + case '*': + operatorType[i] = 2; + subFromNBlock[i] = atoi(offset+1); + break; + default: + operatorType[i] = 0; + subFromNBlock[i] = atoi(offset); } - } - else - { - numberOfRBlocks = 0; - rblockFilename = 0; - rBlockVariable = 0; - maxNumberOfBlock = 0; - indexOfNBlock = 0; - subFromNBlock = 0; - numberOfBlockFixed = 0; - headerLevelOfNBlockIndex = 0; - operatorType = 0; +#ifdef DEBUG + std::cout << "Add rblock index for " << rbNode.attribute("name").value(); + std::cout << " level " << level << " phyindex " << indexOfNBlock[i] << " offset " << offset << std::endl; +#endif + rblockFilename[i] = (char*) rbNode.attribute("name").value(); + + nblockmax += maxNumberOfBlock[i]; } } @@ -367,7 +381,18 @@ SDFBlock::~SDFBlock() void SDFBlock::loadFieldsSDFB(pugi::xml_node rbNode, const pugi::xml_document& doc, std::map<pugi::xml_node, int>& physicalIndex) { - popName = (char*) rbNode.attribute("name").value(); + std::string tmp; + if(strcmp(rbNode.name(),"sourcedatafield") == 0) + { + tmp = std::string(rbNode.parent().attribute("name").value()) + "_sdf"; + } + else + tmp = rbNode.attribute("name").value(); + + popName = (char*) new char[tmp.size()+1]; + strncpy(popName, tmp.c_str(), tmp.size()); + popName[tmp.size()] = 0; + dword indexlist = 0; type = 0; while(blockTypeList[indexlist] != 0) @@ -384,7 +409,6 @@ void SDFBlock::loadFieldsSDFB(pugi::xml_node rbNode, const pugi::xml_document& d this->previous = previous; if(type == 0) { -// cout << "create the type " << popName << endl; type = new SDFBlockType; blockTypeList[indexlist] = type; type->loadType(rbNode, doc, physicalIndex); @@ -423,7 +447,7 @@ void SDFBlock::loadFieldsSDFB(pugi::xml_node rbNode, const pugi::xml_document& d block[nblock].setPreviousPop(&fixed); block[nblock].setRBlockType(indexRBlock); block[nblock].setID(id); - pugi::xml_node childNode = rbNode.child(type->rblockFilename[indexRBlock]); + pugi::xml_node childNode = rbNode.find_child_by_attribute("name", type->rblockFilename[indexRBlock]); block[nblock].loadFieldsSDFB(childNode, doc, physicalIndex); id++; } -- GitLab