Skip to content
Snippets Groups Projects
Commit 2407e0fc authored by Oliver Bock's avatar Oliver Bock
Browse files

First libxml2 implementation

* XPath node search
* Applied for shared memory area parsing
* Should we use it here (CPU consumption)?
* TODO: exception handling!
parent 62762b9f
No related branches found
No related tags found
No related merge requests found
......@@ -20,15 +20,71 @@
#include "Libxml2Adapter.h"
#include <iostream>
#include <sstream>
#include <libxml/xpath.h>
Libxml2Adapter::Libxml2Adapter()
{
m_xmlDocument = NULL;
}
Libxml2Adapter::~Libxml2Adapter()
{
}
string Libxml2Adapter::getAttributeBySingleElementXPath(const string xml, const string xpath)
void Libxml2Adapter::setXmlDocument(const string xml, const string url)
{
//TODO
xmlDocPtr doc = xmlReadMemory(xml.c_str(), xml.size(), url.c_str(), NULL, 0);
if(doc) {
m_xmlDocument = doc;
}
else {
cerr << "Document couldn't be parsed!" << endl;
}
}
string Libxml2Adapter::getSingleNodeContentByXPath(const string xpath)
{
// no document available!
if(!m_xmlDocument) return("");
// prepare xpath search
stringstream buffer;
xmlXPathContextPtr xpathCtx = xmlXPathNewContext(m_xmlDocument);
xmlChar* xpathExpr = xmlCharStrdup(xpath.c_str());
// run xpath query
xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
xmlNodeSetPtr nodes = xpathObj->nodesetval;
// how many nodes did we find?
int size = (nodes) ? nodes->nodeNr : 0;
if(size == 0) {
cerr << "No node found using XPath expression: " << xpath << endl;
return("");
}
else if(size < 1) {
cerr << "More than node found using XPath expression: " << xpath << endl;
return("");
}
// convert xml contents
buffer << xmlNodeListGetString(m_xmlDocument, nodes->nodeTab[0]->xmlChildrenNode, 1);
// clean up
xmlXPathFreeObject(xpathObj);
xmlXPathFreeContext(xpathCtx);
return(buffer.str());
}
string Libxml2Adapter::getSingleNodeContentByXPath(const string xml, const string url, const string xpath)
{
setXmlDocument(xml, url);
return(getSingleNodeContentByXPath(xpath));
}
......@@ -25,6 +25,8 @@
#include "XMLProcessorInterface.h"
#include <libxml/parser.h>
using namespace std;
/**
......@@ -55,19 +57,46 @@ public:
virtual ~Libxml2Adapter();
/**
* \brief Retrieves a single element's attribute value
* \brief Sets the XML document to be processed
*
* \param xml The XML document to be used for processing
* \param url The base URL of the document
*/
void setXmlDocument(const string xml, const string url);
/**
* \brief Retrieves a single node's (element or attribute) content
*
* This method takes a XPath expression that properly defines how to search
* for a specific attribute of a single element. If the XPath search results
* in more than one element or if the attribute can't be found the return
* value is NULL.
* for a specific node (element or attribute). If the XPath search results
* in more than one instance or if the node (or its content) can't be found
* the return value is NULL.
*
* \param xpath The XPath expression to be used for seaching
*
* \return The node's content or NULL in case of an error
*/
string getSingleNodeContentByXPath(const string xpath);
/**
* \brief Retrieves a single node's (element or attribute) content
*
* This method takes a XPath expression that properly defines how to search
* for a specific node (element or attribute). If the XPath search results
* in more than one instance or if the node (or its content) can't be found
* the return value is NULL.
*
* \param xml The XML document to be used for processing
* \param url The base URL of the document
* \param xpath The XPath expression to be used for seaching
*
* \return The attribute value or NULL in case of an error
* \return The node's content or NULL in case of an error
*/
string getAttributeBySingleElementXPath(const string xml, const string xpath);
string getSingleNodeContentByXPath(const string xml, const string url, const string xpath);
private:
/// The current XML document instance
xmlDocPtr m_xmlDocument;
};
/**
......
......@@ -28,6 +28,7 @@ CXX?=g++
# variables
CPPFLAGS = $(shell $(FRAMEWORK_INSTALL)/bin/sdl-config --cflags)
CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/freetype-config --cflags)
CPPFLAGS += $(shell $(FRAMEWORK_INSTALL)/bin/xml2-config --cflags)
CPPFLAGS += -I$(FRAMEWORK_INSTALL)/include/BOINC -I/usr/include
DEPS = Makefile
......
......@@ -51,19 +51,42 @@ public:
virtual ~XMLProcessorInterface() {};
/**
* \brief Retrieves a single element's attribute value
* \brief Sets the XML document to be processed
*
* \param xml The XML document to be used for processing
* \param url The base URL of the document
*/
virtual void setXmlDocument(const string xml, const string url) = 0;
/**
* \brief Retrieves a single node's (element or attribute) content
*
* This method takes a XPath expression that properly defines how to search
* for a specific node (element or attribute). If the XPath search results
* in more than one instance or if the node (or its content) can't be found
* the return value is NULL.
*
* \param xpath The XPath expression to be used for seaching
*
* \return The node's content or NULL in case of an error
*/
virtual string getSingleNodeContentByXPath(const string xpath) = 0;
/**
* \brief Retrieves a single node's (element or attribute) content
*
* This method takes a XPath expression that properly defines how to search
* for a specific attribute of a single element. If the XPath search results
* in more than one element or if the attribute can't be found the return
* value is NULL.
* for a specific node (element or attribute). If the XPath search results
* in more than one instance or if the node (or its content) can't be found
* the return value is NULL.
*
* \param xml The XML document to be used for processing
* \param url The base URL of the document
* \param xpath The XPath expression to be used for seaching
*
* \return The attribute value or NULL in case of an error
* \return The node's content or NULL in case of an error
*/
virtual string getAttributeBySingleElementXPath(const string xml, const string xpath) = 0;
virtual string getSingleNodeContentByXPath(const string xml, const string url, const string xpath) = 0;
};
/**
......
......@@ -19,6 +19,9 @@
***************************************************************************/
#include "EinsteinRadioAdapter.h"
#include "Libxml2Adapter.h"
#include <cstdlib>
const string EinsteinRadioAdapter::SharedMemoryIdentifier = "EinsteinRadio";
......@@ -26,6 +29,7 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
m_WUTemplatePowerSpectrum(POWERSPECTRUM_BINS, 0)
{
this->boincClient = boincClient;
m_xmlIFace = new Libxml2Adapter();
m_WUSkyPosRightAscension = 0.0;
m_WUSkyPosDeclination = 0.0;
......@@ -35,6 +39,7 @@ EinsteinRadioAdapter::EinsteinRadioAdapter(BOINCClientAdapter *boincClient) :
EinsteinRadioAdapter::~EinsteinRadioAdapter()
{
if(m_xmlIFace) delete m_xmlIFace;
}
void EinsteinRadioAdapter::refresh()
......@@ -45,46 +50,42 @@ void EinsteinRadioAdapter::refresh()
void EinsteinRadioAdapter::parseApplicationInformation()
{
char spectrumArray[POWERSPECTRUM_BIN_BYTES + 1] = {0};
string spectrumString;
// get updated application information
string info = boincClient->applicationInformation();
// do we have any data?
if(info.length() > 0) {
string temp;
// parse data into members
// TODO: this is soon going to be replaced by true XML parsing!
if(9 != sscanf(info.c_str(),
"<graphics_info>\n"
" <skypos_rac>%lf</skypos_rac>\n"
" <skypos_dec>%lf</skypos_dec>\n"
" <dispersion>%lf</dispersion>\n"
" <orb_radius>%lf</orb_radius>\n"
" <orb_period>%lf</orb_period\n"
" <orb_phase>%lf</orb_phase>\n"
" <power_spectrum>%80c</power_spectrum>\n"
" <fraction_done>%lf</fraction_done>\n"
" <cpu_time>%lf</cpu_time>\n",
&m_WUSkyPosRightAscension,
&m_WUSkyPosDeclination,
&m_WUDispersionMeasure,
&m_WUTemplateOrbitalRadius,
&m_WUTemplateOrbitalPeriod,
&m_WUTemplateOrbitalPhase,
spectrumArray,
&m_WUFractionDone,
&m_WUCPUTime))
{
cerr << "Incompatible shared memory data encountered!" << endl;
}
else {
m_xmlIFace->setXmlDocument(info, "http://einstein.phys.uwm.edu");
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_rac");
m_WUSkyPosRightAscension = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/skypos_dec");
m_WUSkyPosDeclination = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/dispersion");
m_WUDispersionMeasure = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_radius");
m_WUTemplateOrbitalRadius = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_period");
m_WUTemplateOrbitalPeriod = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/orb_phase");
m_WUTemplateOrbitalPhase = strtod(temp.c_str(), NULL);
spectrumString = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/power_spectrum");
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/fraction_done");
m_WUFractionDone = strtod(temp.c_str(), NULL);
temp = m_xmlIFace->getSingleNodeContentByXPath("/graphics_info/cpu_time");
m_WUCPUTime = strtod(temp.c_str(), NULL);
// TODO: make sure parsing worked flawlessly (only spectrum is checked below!)
// convert radians to degrees
m_WUSkyPosRightAscension *= 180/PI;
m_WUSkyPosDeclination *= 180/PI;
// deserialize power spectrum data
string spectrumString(spectrumArray);
if(spectrumString.length() == POWERSPECTRUM_BIN_BYTES) {
int spectrumBinValue;
// prepare hex to int conversion stream
......@@ -109,7 +110,7 @@ void EinsteinRadioAdapter::parseApplicationInformation()
else {
cerr << "Invalid power spectrum shared memory data encountered!" << endl;
}
}
}
}
......
......@@ -26,6 +26,7 @@
#include <iomanip>
#include "BOINCClientAdapter.h"
#include "XMLProcessorInterface.h"
using namespace std;
......@@ -152,6 +153,9 @@ private:
/// Pointer to the (parent) BOINC client adapter
BOINCClientAdapter *boincClient;
/// Pointer to the XML processor
XMLProcessorInterface* m_xmlIFace;
/// Right ascension of the currently searched sky position (in degrees)
double m_WUSkyPosRightAscension;
......
......@@ -28,12 +28,14 @@ CXX ?= g++
# variables
LIBS = -Wl,-Bstatic -lframework -loglft -L$(STARSPHERE_INSTALL)/lib
LIBS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --libs)
LIBS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --libs)
LIBS += -lboinc_api -lboinc -L/usr/lib
LIBS += -Wl,-Bdynamic $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --static-libs) -lGL -lGLU
CPPFLAGS = -I$(STARSPHERE_INSTALL)/include
CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/sdl-config --cflags)
CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/freetype-config --cflags)
CPPFLAGS += $(shell $(STARSPHERE_INSTALL)/bin/xml2-config --cflags)
CPPFLAGS += -I$(STARSPHERE_INSTALL)/include/BOINC -I/usr/include
DEPS = Makefile
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment