1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-04-02 10:50:07 +03:00

feature #4156: Use secondary groups to schedule. Refactor ObjectXML

class to make use of templates
This commit is contained in:
Ruben S. Montero 2016-01-08 01:06:26 +01:00
parent f27f2c2624
commit 0a25deec55
11 changed files with 419 additions and 311 deletions

View File

@ -20,14 +20,13 @@
#include <string>
#include <vector>
#include <sstream>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
using namespace std;
/**
* This class represents a generic Object supported by a xml document.
* The class provides basic methods to query attributes, and get xml nodes
@ -43,7 +42,7 @@ public:
/**
* Constructs an object using a XML document
*/
ObjectXML(const string &xml_doc);
ObjectXML(const std::string &xml_doc);
/**
* Constructs an object using a XML Node. The node is copied to the new
@ -54,11 +53,25 @@ public:
virtual ~ObjectXML();
/**
* Access Object elements using Xpath
* Gets elements using Xpath expression.
* @param xpath_expr the Xpath of the element
* @return a vector with the elements
*/
vector<string> operator[] (const char * xpath_expr);
void xpaths(std::vector<std::string>& values, const char * xpath_expr);
/* ---------------------------------------------------------------------- */
/* Gets elements, type wrappers. See __xpaths definition for full */
/* description of these methods. */
/* ---------------------------------------------------------------------- */
inline void xpaths(std::vector<int>& values, const char * xpath_expr)
{
__xpaths<int>(values, xpath_expr);
};
inline void xpaths(std::vector<float>& values, const char * xpath_expr)
{
__xpaths<float>(values, xpath_expr);
};
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
@ -69,76 +82,41 @@ public:
*
* @return -1 if default was set
*/
int xpath(string& value, const char * xpath_expr, const char * def);
int xpath(std::string& value, const char * xpath_expr, const char * def);
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(int& value, const char * xpath_expr, const int& def);
/* ---------------------------------------------------------------------- */
/* Gets xpath attribute, type wrappers. See __xpath definition for full */
/* description of these methods. */
/* ---------------------------------------------------------------------- */
inline int xpath(int& v, const char * x, const int& d)
{
return __xpath<int>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(float& value, const char * xpath_expr, const float& def);
inline int xpath(float& v, const char * x, const float& d)
{
return __xpath<float>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(unsigned int& value, const char * xpath_expr,
const unsigned int& def);
inline int xpath(unsigned int& v, const char * x, const unsigned int& d)
{
return __xpath<unsigned int>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(long long& value, const char * xpath_expr,
const long long& def);
inline int xpath(long long& v, const char * x, const long long& d)
{
return __xpath<long long>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(unsigned long long& value, const char * xpath_expr,
const unsigned long long& def);
inline int xpath(unsigned long long& v, const char * x, const unsigned long long& d)
{
return __xpath<unsigned long long>(v, x, d);
}
/**
* Gets and sets a xpath attribute, if the attribute is not found a default
* is used
* @param value to set
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
int xpath(time_t& value, const char * xpath_expr, const time_t& def);
inline int xpath(time_t& v, const char * x, const time_t& d)
{
return __xpath<time_t>(v, x, d);
}
/**
* Gets the value of an element from an xml string
@ -148,7 +126,7 @@ public:
*
* @return -1 if the element was not found
*/
static int xpath_value(string& value, const char *xml, const char *xpath);
static int xpath_value(std::string& value, const char *xml, const char *xpath);
/**
* Search the Object for a given attribute in a set of object specific
@ -158,7 +136,7 @@ public:
*
* @return -1 if the element was not found
*/
virtual int search(const char *name, string& value);
virtual int search(const char *name, std::string& value);
/**
* Search the Object for a given attribute in a set of object specific
@ -179,7 +157,7 @@ public:
* returned as pointers to the object nodes.
* @return the number of nodes found
*/
int get_nodes(const char * xpath_expr, vector<xmlNodePtr>& content);
int get_nodes(const char * xpath_expr, std::vector<xmlNodePtr>& content);
/**
* Adds a copy of the node as a child of the node in the xpath expression.
@ -197,9 +175,9 @@ public:
* Frees a vector of XMLNodes, as returned by the get_nodes function
* @param content the vector of xmlNodePtr
*/
void free_nodes(vector<xmlNodePtr>& content)
void free_nodes(std::vector<xmlNodePtr>& content)
{
vector<xmlNodePtr>::iterator it;
std::vector<xmlNodePtr>::iterator it;
for (it = content.begin(); it < content.end(); it++)
{
@ -212,7 +190,7 @@ public:
* XML resources are freed
* @param xml_doc the new xml document
*/
int update_from_str(const string &xml_doc);
int update_from_str(const std::string &xml_doc);
/**
* Updates the object representation with a new XML document. Previous
@ -227,7 +205,7 @@ public:
* @param xml_doc string to parse
* @return 0 if the xml validates
*/
static int validate_xml(const string &xml_doc);
static int validate_xml(const std::string &xml_doc);
/**
* Renames the nodes given in the xpath expression
@ -250,7 +228,7 @@ public:
* calling function
* @return 0 on success
*/
int eval_bool(const string& expr, bool& result, char **errmsg);
int eval_bool(const std::string& expr, bool& result, char **errmsg);
/**
* Evaluates a rank expression on the given host.
@ -260,19 +238,19 @@ public:
* calling function
* @return 0 on success
*/
int eval_arith(const string& expr, int& result, char **errmsg);
int eval_arith(const std::string& expr, int& result, char **errmsg);
/**
* Function to write the Object in an output stream
*/
friend ostream& operator<<(ostream& os, ObjectXML& oxml)
friend std::ostream& operator<<(std::ostream& os, ObjectXML& oxml)
{
xmlChar * mem;
int size;
xmlDocDumpMemory(oxml.xml,&mem,&size);
string str(reinterpret_cast<char *>(mem));
std::string str(reinterpret_cast<char *>(mem));
os << str;
xmlFree(mem);
@ -305,7 +283,7 @@ private:
/**
* Parse a XML documents and initializes XPath contexts
*/
void xml_parse(const string &xml_doc);
void xml_parse(const std::string &xml_doc);
/**
* Search the Object for a given attribute in a set of object specific
@ -313,7 +291,105 @@ private:
* @param name of the attribute
* @results vector of attributes that matches the query
*/
void search(const char* name, vector<string>& results);
void search(const char* name, std::vector<std::string>& results);
/**
* Gets a xpath attribute, if the attribute is not found a default is used.
* This function only returns the first element
* @param value of the element
* @param xpath_expr of the xml element
* @param def default value if the element is not found
*
* @return -1 if default was set
*/
template<typename T>
int __xpath(T& value, const char * xpath_expr, const T& def)
{
std::vector<std::string> values;
xpaths(values, xpath_expr);
if (values.empty() == true)
{
value = def;
return -1;
}
std::istringstream iss(values[0]);
iss >> std::dec >> value;
if (iss.fail() == true)
{
value = def;
return -1;
}
return 0;
}
/**
* Gets elements by xpath.
* @param values vector with the element values.
* @param expr of the xml element
*/
template<typename T>
void __xpaths(std::vector<T>& values, const char * expr)
{
xmlXPathObjectPtr obj;
xmlNodePtr cur;
xmlChar * str_ptr;
obj=xmlXPathEvalExpression(reinterpret_cast<const xmlChar *>(expr),ctx);
if (obj == 0)
{
return;
}
switch (obj->type)
{
case XPATH_NUMBER:
values.push_back(static_cast<T>(obj->floatval));
break;
case XPATH_NODESET:
for(int i = 0; i < obj->nodesetval->nodeNr ; ++i)
{
cur = obj->nodesetval->nodeTab[i];
if ( cur == 0 || cur->type != XML_ELEMENT_NODE )
{
continue;
}
str_ptr = xmlNodeGetContent(cur);
if (str_ptr != 0)
{
std::istringstream iss(reinterpret_cast<char *>(str_ptr));
T val;
iss >> std::dec >> val;
if (!iss.fail())
{
values.push_back(val);
}
xmlFree(str_ptr);
}
}
break;
default:
break;
}
xmlXPathFreeObject(obj);
};
};
#endif /*OBJECT_XML_H_*/

View File

@ -27,11 +27,13 @@ int ObjectCollection::from_xml_node(const xmlNodePtr node)
ostringstream oss;
vector<string>::iterator it;
vector<string> ids;
ObjectXML oxml(node);
oss << "/" << collection_name << "/ID";
vector<string> ids = oxml[oss.str().c_str()];
oxml.xpaths(ids, oss.str().c_str());
for (it = ids.begin(); it != ids.end(); it++)
{

View File

@ -19,6 +19,7 @@
#include "Log.h"
#include "HostPoolXML.h"
#include "UserPoolXML.h"
#include "ClusterPoolXML.h"
#include "DatastorePoolXML.h"
#include "VirtualMachinePoolXML.h"
@ -54,6 +55,7 @@ protected:
vmapool(0),
dspool(0),
img_dspool(0),
upool(0),
acls(0),
timer(0),
url(""),
@ -76,6 +78,8 @@ protected:
delete dspool;
delete img_dspool;
delete upool;
delete acls;
delete client;
@ -92,6 +96,7 @@ protected:
VirtualMachineActionsPoolXML* vmapool;
SystemDatastorePoolXML * dspool;
ImageDatastorePoolXML * img_dspool;
UserPoolXML * upool;
AclXML * acls;

View File

@ -0,0 +1,57 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef USER_POOL_XML_H_
#define USER_POOL_XML_H_
#include <vector>
#include "PoolXML.h"
#include "UserXML.h"
class UserPoolXML : public PoolXML
{
public:
UserPoolXML(Client* client):PoolXML(client){};
~UserPoolXML(){};
/**
* Gets an object from the pool
* @param oid the object unique identifier
*
* @return a pointer to the object, 0 in case of failure
*/
UserXML * get(int oid) const
{
return static_cast<UserXML *>(PoolXML::get(oid));
};
protected:
int get_suitable_nodes(std::vector<xmlNodePtr>& content)
{
return get_nodes("/USER_POOL/USER", content);
};
void add_object(xmlNodePtr node);
int load_info(xmlrpc_c::value &result);
};
#endif /* USER_POOL_XML_H_ */

View File

@ -0,0 +1,57 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#ifndef USER_XML_H_
#define USER_XML_H_
#include "ObjectXML.h"
class UserXML : public ObjectXML
{
public:
UserXML(const string &xml_doc):ObjectXML(xml_doc)
{
init_attributes();
};
UserXML(const xmlNodePtr node):ObjectXML(node)
{
init_attributes();
};
int get_oid() const
{
return oid;
};
const std::vector<int>& get_gids() const
{
return gids;
};
private:
int oid;
std::vector<int> gids;
void init_attributes()
{
xpath(oid, "/USER/ID", -1);
xpaths(gids,"/USER/GROUPS/ID");
};
};
#endif /* USER_XML_H_ */

View File

@ -53,8 +53,11 @@ void HostXML::init_attributes()
public_cloud = (one_util::toupper(public_cloud_st) == "YES");
//-------------------- HostShare Datastores ------------------------------
vector<string> ds_ids = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/ID"];
vector<string> ds_free = (*this)["/HOST/HOST_SHARE/DATASTORES/DS/FREE_MB"];
vector<string> ds_ids;
vector<string> ds_free;
xpaths(ds_ids, "/HOST/HOST_SHARE/DATASTORES/DS/ID");
xpaths(ds_free,"/HOST/HOST_SHARE/DATASTORES/DS/FREE_MB");
int id;
long long disk;
@ -99,7 +102,9 @@ int HostXML::search(const char *name, int& value)
istringstream iss;
int id;
vector<string> results = (*this)["/HOST/VMS/ID"];
vector<string> results;
xpaths(results, "/HOST/VMS/ID");
for (it=results.begin(); it!=results.end(); it++)
{

View File

@ -27,6 +27,7 @@ source_files=[
'VirtualMachinePoolXML.cc',
'VirtualMachineXML.cc',
'ClusterPoolXML.cc',
'UserPoolXML.cc',
'DatastorePoolXML.cc',
'DatastoreXML.cc']

View File

@ -0,0 +1,62 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2015, OpenNebula Project Leads (OpenNebula.org) */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may */
/* not use this file except in compliance with the License. You may obtain */
/* a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* -------------------------------------------------------------------------- */
#include "UserPoolXML.h"
void UserPoolXML::add_object(xmlNodePtr node)
{
if ( node == 0 || node->children == 0 )
{
NebulaLog::log("USER",Log::ERROR,
"XML Node does not represent a valid user");
return;
}
UserXML* user = new UserXML( node );
objects.insert( pair<int,ObjectXML*>(user->get_oid(), user) );
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int UserPoolXML::load_info(xmlrpc_c::value &result)
{
try
{
client->call(client->get_endpoint(), // serverUrl
"one.userpool.info", // methodName
"s", // arguments format
&result, // resultP
client->get_oneauth().c_str() // argument
);
return 0;
}
catch (exception const& e)
{
ostringstream oss;
oss << "Exception raised: " << e.what();
NebulaLog::log("USER", Log::ERROR, oss);
return -1;
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -321,6 +321,7 @@ void Scheduler::start()
// -------------------------------------------------------------------------
hpool = new HostPoolXML(client);
upool = new UserPoolXML(client);
clpool = new ClusterPoolXML(client);
vmpool = new VirtualMachinePoolXML(client,machines_limit,(live_rescheds==1));
@ -430,8 +431,6 @@ int Scheduler::set_up_pools()
//Cleans the cache and get the datastores
//--------------------------------------------------------------------------
// TODO: Avoid two ds pool info calls to oned
rc = dspool->set_up();
if ( rc != 0 )
@ -450,6 +449,17 @@ int Scheduler::set_up_pools()
//Cleans the cache and get the hosts ids
//--------------------------------------------------------------------------
rc = upool->set_up();
if ( rc != 0 )
{
return rc;
}
//--------------------------------------------------------------------------
//Cleans the cache and get the hosts ids
//--------------------------------------------------------------------------
rc = hpool->set_up();
if ( rc != 0 )
@ -499,6 +509,8 @@ int Scheduler::set_up_pools()
* 2. Meets user/policy requirements
* 3. Have enough capacity to host the VM
*
* @param acl pool
* @param users the user pool
* @param vm the virtual machine
* @param vm_memory vm requirement
* @param vm_cpu vm requirement
@ -511,9 +523,9 @@ int Scheduler::set_up_pools()
* @param error, string describing why the host is not valid
* @return true for a positive match
*/
static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
vector<Attribute *>& vpci, HostXML * host, int &n_auth, int& n_error,
int &n_fits, int &n_matched, string &error)
static bool match_host(AclXML * acls, UserPoolXML * upool, VirtualMachineXML* vm,
int vmem, int vcpu, vector<Attribute *>& vpci, HostXML * host, int &n_auth,
int& n_error, int &n_fits, int &n_matched, string &error)
{
// -------------------------------------------------------------------------
// Filter current Hosts for resched VMs
@ -544,10 +556,17 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
hperms.cid = host->get_cid();
hperms.obj_type = PoolObjectSQL::HOST;
// Only include the VM group ID
UserXML * user = upool->get(vm->get_uid());
set<int> gids;
gids.insert(vm->get_gid());
if (user == 0)
{
error = "User does not exists.";
return false;
}
const vector<int> vgids = user->get_gids();
set<int> gids(vgids.begin(), vgids.end());
if ( !acls->authorize(vm->get_uid(), gids, hperms, AuthRequest::MANAGE))
{
@ -614,6 +633,8 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
* 1. Meet user/policy requirements
* 2. Have enough capacity to host the VM
*
* @param acl pool
* @param users the user pool
* @param vm the virtual machine
* @param vdisk vm requirement
* @param ds to evaluate vm assgiment
@ -624,9 +645,9 @@ static bool match_host(AclXML * acls, VirtualMachineXML* vm, int vmem, int vcpu,
* @param error, string describing why the host is not valid
* @return true for a positive match
*/
static bool match_system_ds(AclXML * acls, VirtualMachineXML* vm, long long vdisk,
DatastoreXML * ds, int& n_auth, int& n_error, int& n_fits, int &n_matched,
string &error)
static bool match_system_ds(AclXML * acls, UserPoolXML * upool,
VirtualMachineXML* vm, long long vdisk, DatastoreXML * ds, int& n_auth,
int& n_error, int& n_fits, int &n_matched, string &error)
{
// -------------------------------------------------------------------------
// Check if user is authorized
@ -637,10 +658,17 @@ static bool match_system_ds(AclXML * acls, VirtualMachineXML* vm, long long vdis
ds->get_permissions(dsperms);
// Only include the VM group ID
UserXML * user = upool->get(vm->get_uid());
set<int> gids;
gids.insert(vm->get_gid());
if (user == 0)
{
error = "User does not exists.";
return false;
}
const vector<int> vgids = user->get_gids();
set<int> gids(vgids.begin(), vgids.end());
if ( !acls->authorize(vm->get_uid(), gids, dsperms, AuthRequest::USE))
{
@ -740,6 +768,7 @@ void Scheduler::match_schedule()
const map<int, ObjectXML*> pending_vms = vmpool->get_objects();
const map<int, ObjectXML*> hosts = hpool->get_objects();
const map<int, ObjectXML*> datastores = dspool->get_objects();
const map<int, ObjectXML*> users = upool->get_objects();
double total_match_time = 0;
double total_rank_time = 0;
@ -790,8 +819,8 @@ void Scheduler::match_schedule()
{
host = static_cast<HostXML *>(h_it->second);
if (match_host(acls, vm, vm_memory, vm_cpu, vm_pci, host, n_auth,
n_error, n_fits, n_matched, m_error))
if (match_host(acls, upool, vm, vm_memory, vm_cpu, vm_pci, host,
n_auth, n_error, n_fits, n_matched, m_error))
{
vm->add_match_host(host->get_hid());
@ -894,8 +923,8 @@ void Scheduler::match_schedule()
{
ds = static_cast<DatastoreXML *>(h_it->second);
if (match_system_ds(acls, vm, vm_disk, ds, n_auth, n_error, n_fits,
n_matched, m_error))
if (match_system_ds(acls, upool, vm, vm_disk, ds, n_auth, n_error,
n_fits, n_matched, m_error))
{
vm->add_match_datastore(ds->get_oid());

View File

@ -19,10 +19,13 @@
#include <cstring>
#include <iostream>
#include <sstream>
using namespace std;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
ObjectXML::ObjectXML(const string &xml_doc):paths(0),num_paths(0),xml(0),ctx(0)
ObjectXML::ObjectXML(const std::string &xml_doc):paths(0),num_paths(0),xml(0),ctx(0)
{
try
{
@ -85,21 +88,19 @@ ObjectXML::~ObjectXML()
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
vector<string> ObjectXML::operator[] (const char * xpath_expr)
void ObjectXML::xpaths(std::vector<std::string>& content, const char * expr)
{
xmlXPathObjectPtr obj;
vector<string> content;
ostringstream oss;
std::ostringstream oss;
xmlNodePtr cur;
xmlChar * str_ptr;
obj = xmlXPathEvalExpression(
reinterpret_cast<const xmlChar *>(xpath_expr), ctx);
obj = xmlXPathEvalExpression(reinterpret_cast<const xmlChar *>(expr), ctx);
if (obj == 0)
{
return content;
return;
}
switch (obj->type)
@ -124,9 +125,9 @@ vector<string> ObjectXML::operator[] (const char * xpath_expr)
if (str_ptr != 0)
{
string element_content = reinterpret_cast<char *>(str_ptr);
std::string ncontent = reinterpret_cast<char *>(str_ptr);
content.push_back(element_content);
content.push_back(ncontent);
xmlFree(str_ptr);
}
@ -146,8 +147,6 @@ vector<string> ObjectXML::operator[] (const char * xpath_expr)
}
xmlXPathFreeObject(obj);
return content;
};
/* -------------------------------------------------------------------------- */
@ -158,7 +157,7 @@ int ObjectXML::xpath(string& value, const char * xpath_expr, const char * def)
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
xpaths(values, xpath_expr);
if ( values.empty() == true )
{
@ -176,215 +175,28 @@ int ObjectXML::xpath(string& value, const char * xpath_expr, const char * def)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(int& value, const char * xpath_expr, const int& def)
{
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
if (values.empty() == true)
{
value = def;
rc = -1;
}
else
{
istringstream iss;
iss.str(values[0]);
iss >> dec >> value;
if (iss.fail() == true)
{
value = def;
rc = -1;
}
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(float& value, const char * xpath_expr, const float& def)
{
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
if (values.empty() == true)
{
value = def;
rc = -1;
}
else
{
istringstream iss;
iss.str(values[0]);
iss >> dec >> value;
if (iss.fail() == true)
{
value = def;
rc = -1;
}
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(unsigned int& value, const char * xpath_expr,
const unsigned int& def)
{
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
if (values.empty() == true)
{
value = def;
rc = -1;
}
else
{
istringstream iss;
iss.str(values[0]);
iss >> dec >> value;
if (iss.fail() == true)
{
value = def;
rc = -1;
}
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(long long& value, const char * xpath_expr,
const long long& def)
{
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
if (values.empty() == true)
{
value = def;
rc = -1;
}
else
{
istringstream iss;
iss.str(values[0]);
iss >> dec >> value;
if (iss.fail() == true)
{
value = def;
rc = -1;
}
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(unsigned long long& value, const char * xpath_expr,
const unsigned long long& def)
{
vector<string> values;
int rc = 0;
values = (*this)[xpath_expr];
if (values.empty() == true)
{
value = def;
rc = -1;
}
else
{
istringstream iss;
iss.str(values[0]);
iss >> dec >> value;
if (iss.fail() == true)
{
value = def;
rc = -1;
}
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath(time_t& value, const char * xpath_expr, const time_t& def)
{
unsigned long long int_val;
unsigned long long int_def = static_cast<time_t>(def);
int rc;
rc = xpath(int_val, xpath_expr, int_def);
value = static_cast<time_t>(int_val);
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int ObjectXML::xpath_value(string& value,const char *doc,const char *the_xpath)
{
int rc = 0;
try
{
ObjectXML obj(doc);
vector<string> values;
values = obj[the_xpath];
obj.xpaths(values, the_xpath);
if (values.empty() == true)
{
rc = -1;
}
else
{
value = values[0];
return -1;
}
value = values[0];
}
catch(runtime_error& re)
{
rc = -1;
return -1;
}
return rc;
return 0;
}
/* -------------------------------------------------------------------------- */
@ -736,7 +548,7 @@ void ObjectXML::search(const char* name, vector<string>& results)
if (name[0] == '/')
{
results = (*this)[name];
xpaths(results, name);
}
else if (num_paths == 0)
{
@ -753,7 +565,7 @@ void ObjectXML::search(const char* name, vector<string>& results)
xpath << '|' << paths[i] << name;
}
results = (*this)[xpath.str().c_str()];
xpaths(results, xpath.str().c_str());
}
}

View File

@ -84,6 +84,8 @@
#include "expr_bool.h"
#include "ObjectXML.h"
using namespace std;
#define YYERROR_VERBOSE
#define expr_bool__lex expr_lex