From cd242921709e33184e296541df747882f0dcec29 Mon Sep 17 00:00:00 2001 From: Oliver Bock <oliver.bock@aei.mpg.de> Date: Wed, 3 Sep 2008 18:58:03 +0200 Subject: [PATCH] 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) --- src/framework/BOINCClientAdapter.cpp | 73 +++++++++++++++++++++++++--- src/framework/BOINCClientAdapter.h | 9 +++- src/framework/Libxml2Adapter.cpp | 8 +-- src/framework/Libxml2Adapter.h | 4 +- 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/framework/BOINCClientAdapter.cpp b/src/framework/BOINCClientAdapter.cpp index d999271..ef587e7 100644 --- a/src/framework/BOINCClientAdapter.cpp +++ b/src/framework/BOINCClientAdapter.cpp @@ -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,15 +39,18 @@ BOINCClientAdapter::BOINCClientAdapter(string sharedMemoryIdentifier) BOINCClientAdapter::~BOINCClientAdapter() { + if(m_xmlIFace) delete m_xmlIFace; } void BOINCClientAdapter::initialize() { - readUserInfo(); - readSharedMemoryArea(); - readProjectPreferences(); + if(!m_Initialized) { + readUserInfo(); + readSharedMemoryArea(); + readProjectPreferences(); - m_Initialized = true; + 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 diff --git a/src/framework/BOINCClientAdapter.h b/src/framework/BOINCClientAdapter.h index d8689ab..ee5d5c4 100644 --- a/src/framework/BOINCClientAdapter.h +++ b/src/framework/BOINCClientAdapter.h @@ -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; }; /** diff --git a/src/framework/Libxml2Adapter.cpp b/src/framework/Libxml2Adapter.cpp index 07186c3..ead673d 100644 --- a/src/framework/Libxml2Adapter.cpp +++ b/src/framework/Libxml2Adapter.cpp @@ -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 diff --git a/src/framework/Libxml2Adapter.h b/src/framework/Libxml2Adapter.h index 92ca84b..d4fb1c9 100644 --- a/src/framework/Libxml2Adapter.h +++ b/src/framework/Libxml2Adapter.h @@ -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); -- GitLab