Skip to content
Snippets Groups Projects
Commit a00ecf3e authored by Andrea Zoli's avatar Andrea Zoli
Browse files

Remove XmlConfig class.

parent ef858038
Branches
Tags
No related merge requests found
/***************************************************************************
begin : Tue May 20 2014
copyright : (C) 2014 Andrea Zoli
email : zoli@iasfbo.inaf.it
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef PACKETLIB_XMLCONFIG_H
#define PACKETLIB_XMLCONFIG_H
#include <string>
#include <fstream>
#include <map>
#include "pugixml.h"
namespace PacketLib
{
class XmlConfig
{
const static std::string _fixed32[];
const static std::string _fixed64[];
std::map<pugi::xml_node, int> _physicalIndex;
void _cachePhysicalIndexes(pugi::xml_node node);
void _writeFields(pugi::xml_node parent, std::fstream& fs);
void _writeRBlock(pugi::xml_node rblock, std::fstream& fs, pugi::xml_document& doc);
public:
std::string convert(const std::string& filename);
};
}
#endif
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "ConfigurationFile.h" #include "ConfigurationFile.h"
#include "InputTextFile.h" #include "InputTextFile.h"
#include "XmlConfig.h"
#include <unistd.h> #include <unistd.h>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
...@@ -44,20 +43,6 @@ bool ConfigurationFile::open(char** parameters) throw(PacketExceptionIO*) ...@@ -44,20 +43,6 @@ bool ConfigurationFile::open(char** parameters) throw(PacketExceptionIO*)
bool ret; bool ret;
currentpwd = getcwd(NULL, 512L); currentpwd = getcwd(NULL, 512L);
if(std::string(parameters[0]).find(".xml") != std::string::npos)
{
std::string confdir(parameters[0]);
confdir.erase(std::find(confdir.rbegin(), confdir.rend(), '/').base(), confdir.end());
chdir(confdir.c_str());
XmlConfig config;
std::string streamfile = confdir + config.convert(parameters[0]);
int size = streamfile.size();
parameters[0] = new char[size+1];
memcpy(parameters[0], streamfile.c_str(), size);
parameters[0][size] = 0;
chdir(currentpwd);
}
ret = InputTextFile::open(parameters); ret = InputTextFile::open(parameters);
if(!closed) if(!closed)
fchdir(); fchdir();
......
/***************************************************************************
begin : Tue May 20 2014
copyright : (C) 2014 Andrea Zoli
email : zoli@iasfbo.inaf.it
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "XmlConfig.h"
#include <iostream>
#include <cstdlib>
#include <vector>
namespace PacketLib
{
using namespace pugi;
using namespace std;
const std::string XmlConfig::_fixed32[] = { "uint32", "int32", "float" };
const std::string XmlConfig::_fixed64[] = { "uint64", "int64", "double" };
void XmlConfig::_cachePhysicalIndexes(xml_node node)
{
unsigned 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 XmlConfig::_writeFields(xml_node parent, fstream& fs)
{
unsigned int index = 0;
for(pugi::xml_node_iterator it=parent.begin(); it != parent.end(); ++it)
{
if(string(it->name()).compare("field") != 0)
continue;
// write 32bits fields
fs << "-- field " << index << endl;
string name = it->attribute("name").value();
fs << name << endl;
string typeStr = it->attribute("type").value();
bool found = false;
for(unsigned int i=0; i<3; i++)
{
if(typeStr.compare(_fixed32[i]) == 0)
{
fs << "16" << endl;
fs << "none" << endl;
index++;
fs << "-- field " << index << endl;
fs << name+"__2" << endl;
fs << "16" << endl;
fs << "none" << endl;
index++;
found = true;
break;
}
}
if(found)
continue;
// write 64bits fields
for(unsigned int i=0; i<3; i++)
{
if(typeStr.compare(_fixed64[i]) == 0)
{
fs << "16" << endl;
fs << "none" << endl;
fs << "-- field " << index << endl;
fs << name+"__2" << endl;
fs << "16" << endl;
fs << "none" << endl;
index++;
fs << "-- field " << index << endl;
fs << name+"__3" << endl;
fs << "16" << endl;
fs << "none" << endl;
index++;
fs << "-- field " << index << endl;
fs << name+"__4" << endl;
fs << "16" << endl;
fs << "none" << endl;
index++;
found = true;
break;
}
}
if(found)
continue;
// write <= 16 bits fields
string::size_type spos = typeStr.find_first_of("0123456789");
string::size_type epos = typeStr.find_last_of("0123456789");
int nbits = atoi(typeStr.substr(spos, epos+1).c_str());
fs << nbits << endl;
xml_attribute constvalue = it->attribute("constvalue");
if(!constvalue)
fs << "none" << endl;
else
fs << constvalue.value() << endl;
index++;
}
}
void XmlConfig::_writeRBlock(xml_node rblock, fstream& fs, xml_document& doc)
{
#ifdef DEBUG
if(string(rblock.name()).compare("rblock") == 0)
std::cout << "Writing " << rblock.attribute("name").value() << ".rblock .." << endl;
#endif
fs << "[RBlock Configuration]" << endl;
fs << "-- fixed part present (yes | no)" << endl;
if(rblock.child("field"))
fs << "yes" << endl;
else
fs << "no" << endl;
fs << "-- variable part present (yes | no). If yes, add [RBlockX] sections." << endl;
vector<xml_node> rblocks;
for(pugi::xml_node_iterator it=rblock.begin(); it != rblock.end(); ++it)
if(string(it->name()).compare("rblock") == 0)
rblocks.push_back(*it);
if(rblocks.size() > 0)
{
fs << "yes" << endl;
fs << "--number of rblock (if variable part is present)" << endl;
fs << rblocks.size() << endl;
}
else
fs << "no" << endl;
if(rblock.child("field"))
{
fs << "[Fixed Part]" << endl;
_writeFields(rblock, fs);
}
if(rblocks.size() > 0)
{
for(unsigned int i=0; i<rblocks.size(); i++)
{
fs << "[RBlock" << i+1 << "]" << endl;
fs << "--type of number of blocks of this variable part: fixed = number of block fixed equals to max number of block (fixed | variable)" << endl;
xml_attribute idref = rblocks[i].attribute("idref");
if(idref)
fs << "variable" << endl;
else
fs << "fixed" << endl;
fs << "--number of blocks for fixed value into variable part, max number of blocks for variable value into variable part" << endl;
fs << rblocks[i].attribute("maxnumberofblocks").value() << endl;
fs << "-- for variable block, number of level of headers in which is present the field with the number of blocks of the variable part (0: fixed part)" << endl;
if(!idref)
fs << "0" << endl;
else
{
#ifdef DEBUG
cout << "rblock name='" << rblocks[i].attribute("name").value() << "' idref='" << rblocks[i].attribute("idref").value() << "' ";
#endif
string query = string("//field[@id=\"")+idref.value()+"\"]";
xml_node numberofblocksid = doc.select_nodes(query.c_str())[0].node();
xml_node nodetmp = rblocks[i];
unsigned int level = 0;
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)
{
// we add just one level for the same reason above
level++;
}
else
{
cerr << "Error on id association. Id '" << idref.value() << "' doesn't exists. ";
cerr << "idref defined by rblock '" << rblocks[i].attribute("name").value() << "'." << endl;
exit(0);
}
break;
}
level++;
nodetmp = nodetmp.parent();
}
#ifdef DEBUG
cout << "levels=" << level << endl;
#endif
fs << level << endl;
fs << "-- for variable block, index of field of the header which rappresent the number of events (the number of blocks) of the packet" << endl;
fs << _physicalIndex[numberofblocksid] << endl;
fs << "-- for variable block, value to sum to get the real number of events (blocks)" << endl;
xml_attribute offset = numberofblocksid.attribute("numberofblocksoffset");
if(offset)
fs << offset.value() << endl;
else
fs << "0" << endl;
}
string rblockFilename=rblocks[i].attribute("name").value();
rblockFilename+=".rblock";
fs << rblockFilename << endl;
fstream rfs;
rfs.open(rblockFilename.c_str(), ios_base::out);
_writeRBlock(rblocks[i], rfs, doc);
rfs.close();
}
}
}
std::string XmlConfig::convert(const std::string& filename)
{
xml_document doc;
if (!doc.load_file(filename.c_str()))
{
cerr << "Cannot load " << filename << endl;
return "";
}
// cache all the field physical indexes
xpath_node_set fieldParents = doc.select_nodes("//*[field]");
for(xpath_node_set::const_iterator it = fieldParents.begin(); it != fieldParents.end(); ++it)
_cachePhysicalIndexes(it->node());
xml_node stream = doc.child("stream");
string streamFilename = string(stream.attribute("name").value()) + ".stream";
xml_node header = stream.child("header");
string headerFilename = string(header.attribute("name").value()) + ".header";
/// Write header file
fstream hfs;
hfs.open(headerFilename.c_str(), ios_base::out);
#ifdef DEBUG
cout << "Writing " << headerFilename << " .." << endl;
#endif
hfs << "-- name of header" << endl;
hfs << header.attribute("description").value() << endl;
hfs << "-- number of field with dimension of packet (or first field if dim of packet is stored in a 32 bit field)" << endl;
string query = string("//field[@id=\"")+header.attribute("idref").value()+"\"]";
xml_node packetLength = header.select_nodes(query.c_str())[0].node();
hfs << _physicalIndex[packetLength] << endl;
hfs << "-- 16 or 32 bit size dimension of the packet lenght" << endl;
string typeStr = packetLength.attribute("type").value();
string::size_type spos = typeStr.find_first_of("0123456789");
string::size_type epos = typeStr.find_last_of("0123456789");
int nbits = atoi(typeStr.substr(spos, epos+1).c_str());
hfs << nbits << endl;
hfs << "[Field]" << endl;
_writeFields(header, hfs);
// query for compression algorithm / compression level
xpath_node_set compression_algorithm = header.select_nodes("field[@id=\"packetlib:compression_algorithm\"]");
xpath_node_set compression_level = header.select_nodes("field[@id=\"packetlib:compression_level\"]");
/// Write packet files
vector<string> packetFilenames;
xml_node packet = stream.child("packet");
fstream pfs;
while(packet)
{
string packetFilename = string(packet.attribute("name").value()) + ".packet";
packetFilenames.push_back(packetFilename);
pfs.close();
pfs.open(packetFilename.c_str(), ios_base::out);
#ifdef DEBUG
cout << "Writing " << packetFilename << " .." << endl;
#endif
pfs << "-- name of packet - " << packet.attribute("description").value() << endl;
pfs << packet.attribute("name").value() << endl;
pfs << "[PacketHeader]" << endl;
pfs << "-- file that contains the description of the header" << endl;
pfs << headerFilename << endl;
pfs << "[DataFieldHeader]" << endl;
xml_node datafieldheader = packet.child("datafieldheader");
_writeFields(datafieldheader, pfs);
pfs << "[SourceDataField]" << endl;
pfs << "-- type of packet: noblock, block, rblock (with recoursive block)" << endl;
pfs << "rblock" << endl;
xml_node sourcedatafield = packet.child("sourcedatafield");
_writeRBlock(sourcedatafield, pfs, doc);
pfs << "[Identifiers]" << endl;
xpath_node_set packetids = packet.select_nodes("identifiers/identifier");
unsigned int counter = 0;
for(xpath_node_set::const_iterator it = packetids.begin(); it != packetids.end(); ++it)
{
pfs << "-- ID" << counter << endl;
pfs << "-- field number" << endl;
xml_node identifier = it->node();
string query = string("//field[@id=\"")+identifier.attribute("idref").value()+"\"]";
xml_node fieldid = doc.select_nodes(query.c_str())[0].node();
pfs << _physicalIndex[fieldid] << endl;
pfs << "-- type (0 header, 1 data field, 2 source data field)" << endl;
string parentName = fieldid.parent().name();
int index = -1;
if(parentName.compare("header") == 0)
index = 0;
else if(parentName.compare("datafieldheader") == 0)
index = 1;
else if(parentName.compare("sourcedatafield") == 0)
index = 2;
pfs << index << endl;
pfs << "-- value" << endl;
pfs << identifier.attribute("value").value() << endl;
counter++;
}
xml_node tail = packet.child("tail");
if(tail)
{
pfs << "[Tail]" << endl;
_writeFields(tail, pfs);
}
// if not defined in the header find in datafieldheader
int algindex = 0;
if(compression_algorithm.empty())
{
compression_algorithm = datafieldheader.select_nodes("field[@id=\"packetlib:compression_algorithm\"]");
algindex = 1;
}
// and sourcedatafield
if(compression_algorithm.empty())
{
algindex = 2;
compression_algorithm = sourcedatafield.select_nodes("@field[id=\"packetlib:compression_algorithm\"]");
}
// if not defined in the header find in datafieldheader
int lvlindex = 0;
if(compression_level.empty())
{
compression_level = datafieldheader.select_nodes("field[@id=\"packetlib:compression_level\"]");
lvlindex = 1;
}
// and sourcedatafield
if(compression_level.empty())
{
lvlindex = 2;
compression_level = sourcedatafield.select_nodes("@field[id=\"packetlib:compression_level\"]");
}
if(!compression_algorithm.empty() && !compression_level.empty())
{
pfs << "[Compression]" << endl;
pfs << _physicalIndex[compression_algorithm[0].node()] << endl;
pfs << algindex << endl;
pfs << _physicalIndex[compression_level[0].node()] << endl;
pfs << lvlindex << endl;
}
packet=packet.next_sibling();
}
/// Write stream file
fstream sfs;
sfs.open(streamFilename.c_str(), ios_base::out);
#ifdef DEBUG
cout << "Writing " << streamFilename << " .." << endl;
#endif
sfs << "[Configuration]" << endl;
bool prefix = false;
sfs << "--prefix" << endl;
if(prefix)
sfs << "true" << endl;
else
sfs << "false" << endl;
sfs << "--stream format bigendian" << endl;
xml_attribute bigendian = stream.attribute("bigendian");
if(bigendian.empty())
sfs << "false" << endl;
else
sfs << bigendian.value() << endl;
sfs << "--dimension of prefix" << endl;
xml_attribute prefixsize = stream.attribute("prefixsize");
if(!prefixsize)
sfs << "0" << endl;
else
sfs << prefixsize.value() << endl;
sfs << "[Header Format]" << endl;
sfs << headerFilename << endl;
sfs << "[Packet Format]" << endl;
for(unsigned int i=0; i<packetFilenames.size(); i++)
sfs << packetFilenames[i] << endl;
#ifdef DEBUG
cout << "Conversion complete." << endl;
#endif
return streamFilename;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment