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

Implemented XML parsing for project preferences

* Parsing uses XPath searches on DOM tree (only done once during initialization)
* Also: improved initialization
* Also: fixed/improved XML adapter (revert b1f8ac4391c33079f12164d3c1057dc95343e341)
parent 95652f60
Branches
Tags
No related merge requests found
......@@ -19,6 +19,9 @@
***************************************************************************/
#include "BOINCClientAdapter.h"
#include "Libxml2Adapter.h"
#include <sstream>
BOINCClientAdapter::BOINCClientAdapter(string sharedMemoryIdentifier)
{
......@@ -26,6 +29,8 @@ BOINCClientAdapter::BOINCClientAdapter(string sharedMemoryIdentifier)
m_SharedMemoryAreaIdentifier = sharedMemoryIdentifier;
m_SharedMemoryAreaAvailable = false;
m_xmlIFace = new Libxml2Adapter();
m_GraphicsFrameRate = 20;
m_GraphicsQualitySetting = BOINCClientAdapter::LowGraphicsQualitySetting;
m_GraphicsWindowWidth = 800;
......@@ -34,16 +39,19 @@ BOINCClientAdapter::BOINCClientAdapter(string sharedMemoryIdentifier)
BOINCClientAdapter::~BOINCClientAdapter()
{
if(m_xmlIFace) delete m_xmlIFace;
}
void BOINCClientAdapter::initialize()
{
if(!m_Initialized) {
readUserInfo();
readSharedMemoryArea();
readProjectPreferences();
m_Initialized = true;
}
}
void BOINCClientAdapter::refresh()
{
......@@ -54,7 +62,7 @@ void BOINCClientAdapter::refresh()
/// \todo Check that we're still watching our own WU (or science app)!
}
else {
cerr << "The BOINC Client Adapter has not yet been initialized! Doing so now...";
cerr << "The BOINC Client Adapter has not yet been initialized! Doing so now..." << endl;
initialize();
}
}
......@@ -91,7 +99,52 @@ void BOINCClientAdapter::readSharedMemoryArea()
void BOINCClientAdapter::readProjectPreferences()
{
string temp;
istringstream convertor;
convertor.exceptions(ios_base::badbit | ios_base::failbit);
// prepare xml document
m_xmlIFace->setXmlDocument(projectInformation(), "http://einstein.phys.uwm.edu");
// use XPath queries to get attributes
try {
temp = m_xmlIFace->getSingleNodeContentByXPath("/project_preferences/graphics/@fps");
if(temp.length() > 0) {
convertor.str(temp);
convertor >> dec >> m_GraphicsFrameRate;
convertor.clear();
}
temp = m_xmlIFace->getSingleNodeContentByXPath("/project_preferences/graphics/@quality");
if(temp.length() > 0) {
if(temp == "high") {
m_GraphicsQualitySetting = BOINCClientAdapter::HighGraphicsQualitySetting;
}
else if(temp == "medium") {
m_GraphicsQualitySetting = BOINCClientAdapter::MediumGraphicsQualitySetting;
}
else {
m_GraphicsQualitySetting = BOINCClientAdapter::LowGraphicsQualitySetting;
}
}
temp = m_xmlIFace->getSingleNodeContentByXPath("/project_preferences/graphics/@width");
if(temp.length() > 0) {
convertor.str(temp);
convertor >> dec >> m_GraphicsWindowWidth;
convertor.clear();
}
temp = m_xmlIFace->getSingleNodeContentByXPath("/project_preferences/graphics/@height");
if(temp.length() > 0) {
convertor.str(temp);
convertor >> dec >> m_GraphicsWindowHeight;
convertor.clear();
}
}
catch(ios_base::failure) {
cerr << "Error parsing project preferences! Using defaults..." << endl;
}
}
string BOINCClientAdapter::applicationInformation() const
......@@ -101,8 +154,12 @@ string BOINCClientAdapter::applicationInformation() const
string BOINCClientAdapter::projectInformation() const
{
// TODO: check if we have to add the <project_specific> tag!
return m_UserData.project_preferences;
// ugly workaround for incomplete XML fragment returned by BOINC!
string temp = "<project_preferences>\n";
temp += m_UserData.project_preferences;
temp += "</project_preferences>\n";
return temp;
}
int BOINCClientAdapter::graphicsFrameRate() const
......
......@@ -28,6 +28,8 @@
#include "boinc_api.h"
#include "graphics2.h"
#include "XMLProcessorInterface.h"
using namespace std;
/**
......@@ -226,7 +228,7 @@ public:
* (not yet literally a XML schema, will be provided later) with respect to graphics settings:
*
\verbatim
<project_specific>
<project_preferences>
<graphics fps="20" quality="low" width="800" height="600">
<starsphere>
<feature id="globe" enabled="true" />
......@@ -235,7 +237,7 @@ public:
<feature id="sound" enabled="false" />
</waverider>
</graphics>
</project_specific>
</project_preferences>
\endverbatim
*
* The \c graphics tag and its four attributes \b must be provided as shown above where
......@@ -380,6 +382,9 @@ private:
* user account, work unit and computation session.
*/
APP_INIT_DATA m_UserData;
/// Pointer to the XML processor
XMLProcessorInterface* m_xmlIFace;
};
/**
......
......@@ -32,6 +32,8 @@ Libxml2Adapter::Libxml2Adapter()
Libxml2Adapter::~Libxml2Adapter()
{
if(m_xmlDocument) xmlFreeDoc(m_xmlDocument);
xmlCleanupParser();
}
void Libxml2Adapter::setXmlDocument(const string xml, const string url)
......@@ -48,7 +50,7 @@ void Libxml2Adapter::setXmlDocument(const string xml, const string url)
string Libxml2Adapter::getSingleNodeContentByXPath(const string xpath)
{
// no document available!
if(!m_xmlDocument) return(NULL);
if(!m_xmlDocument) return("");
// prepare xpath search
stringstream buffer;
......@@ -64,11 +66,11 @@ string Libxml2Adapter::getSingleNodeContentByXPath(const string xpath)
if(size == 0) {
cerr << "No node found using XPath expression: " << xpath << endl;
return(NULL);
return("");
}
else if(size < 1) {
cerr << "More than node found using XPath expression: " << xpath << endl;
return(NULL);
return("");
}
// convert xml contents
......
......@@ -84,13 +84,13 @@ public:
* 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.
* the return value is an empty string.
*
* \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 node's content or NULL in case of an error
* \return The node's content or an empty string in case of an error
*/
string getSingleNodeContentByXPath(const string xml, const string url, const string xpath);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment