Added documentation.

Made getFloat() more explicit. Took out the use of "-" for type. Now,
have to specify the type of units conversion.
This commit is contained in:
Harry Moffat 2008-10-31 15:45:00 +00:00
parent 22ba9fd676
commit 75e56cf8d3
4 changed files with 291 additions and 134 deletions

View file

@ -222,47 +222,97 @@ namespace ctml {
}
/**
* Get a floating-point value from a child element. Returns a
* double value for the child named 'name' of element 'parent'. If
* 'type' is supplied and matches a known unit type, unit
* conversion to SI will be done if the child element has an attribute
* 'units'.
*/
doublereal getFloat(const XML_Node& parent, string name, string type) {
if (!parent.hasChild(name))
throw CanteraError("getFloat (called from XML Node \"" +
parent.name() + "\"): ",
"no child XML element named " + name);
const XML_Node& node = parent.child(name);
doublereal x, x0, x1, fctr = 1.0;
string units, vmin, vmax;
x = atof(node().c_str());
x0 = Undef;
x1 = Undef;
units = node["units"];
vmin = node["min"];
vmax = node["max"];
if (vmin != "") {
x0 = atof(vmin.c_str());
if (x < x0 - Tiny) {
writelog("\nWarning: value "+node()+" is below lower limit of "
+vmin+".\n");
}
}
if (node["max"] != "") {
x1 = atof(vmax.c_str());
if (x > x1 + Tiny) {
writelog("\nWarning: value "+node()+" is above upper limit of "
+vmax+".\n");
}
}
if (type == "actEnergy" && units != "")
fctr = actEnergyToSI(units);
else if (type != "" && units != "")
fctr = toSI(units);
return fctr*x;
// Get a floating-point value from a child element.
/*
* Returns a double value for the child named 'name' of element 'parent'. If
* 'type' is supplied and matches a known unit type, unit
* conversion to SI will be done if the child element has an attribute
* 'units'.
*
* Note, it's an error for the child element not to exist.
*
* Example:
*
* Code snipet:
* @verbatum
const XML_Node &State_XMLNode;
doublereal pres = OneAtm;
if (state_XMLNode.hasChild("pressure")) {
pres = getFloat(State_XMLNode, "pressure", "toSI");
}
@endverbatum
*
* reads the corresponding XML file:
* @verbatum
<state>
<pressure units="Pa"> 101325.0 </pressure>
<\state>
@endverbatum
*
* @param parent reference to the XML_Node object of the parent XML element
* @param name Name of the XML child element
* @param type String type. Currently known types are "toSI" and "actEnergy",
* and "" , for no conversion. The default value is ""
* which implies that no conversion is allowed.
*/
doublereal getFloat(const XML_Node& parent, string name, string type) {
if (!parent.hasChild(name))
throw CanteraError("getFloat (called from XML Node \"" +
parent.name() + "\"): ",
"no child XML element named \"" + name + "\" exists");
const XML_Node& node = parent.child(name);
doublereal x, x0, x1, fctr = 1.0;
string units, vmin, vmax;
x = atof(node().c_str());
x0 = Undef;
x1 = Undef;
units = node["units"];
vmin = node["min"];
vmax = node["max"];
if (vmin != "") {
x0 = atof(vmin.c_str());
if (x < x0 - Tiny) {
writelog("\nWarning: value "+node()+" is below lower limit of "
+vmin+".\n");
}
}
if (node["max"] != "") {
x1 = atof(vmax.c_str());
if (x > x1 + Tiny) {
writelog("\nWarning: value "+node()+" is above upper limit of "
+vmax+".\n");
}
}
// Note, most type's of converters default to toSI() type atm.
// This may change and become more specific in the future.
if (type == "actEnergy" && units != "") {
fctr = actEnergyToSI(units);
} else if (type == "toSI" && units != "") {
fctr = toSI(units);
} else if (type == "temperature" && units != "") {
fctr = toSI(units);
} else if (type == "density" && units != "") {
fctr = toSI(units);
} else if (type == "pressure" && units != "") {
fctr = toSI(units);
} else if (type != "" && units != "") {
fctr = toSI(units);
#ifdef DEBUG_MODE
writelog("\nWarning: conversion toSI() was done on node value " + node.name() +
"but wasn't explicity requested. Type was \"" + type + "\"\n");
#endif
}
// Note, below currently produces a lot of output due to transport blocks.
// This needs to be addressed.
#ifdef DEBUG_MODE_MORE
else if (type == "" && units != "") {
writelog("\nWarning: XML node " + node.name() +
"has a units attribute, \"" + units + "\","
"but no conversion was done because the getFloat() command didn't have a type\n");
}
#endif
return fctr*x;
}
/**
@ -416,46 +466,47 @@ namespace ctml {
}
}
/**
* This function interprets the value portion of an XML element
* as a series of "Pairs" separated by white space.
* Each pair consists of nonwhite-space characters.
* The first ":" found in the pair string is used to separate
* the string into two parts. The first part is called the "key"
* The second part is called the "val".
* String vectors of key[i] and val[i] are returned in the
* argument list.
* Warning: No spaces are allowed in each pair. Quotes are part
* of the string.
* Example
* <xmlNode>
* red:112 blue:34
* green:banana
* </xmlNode>
*
* Returns:
* key val
* 0: "red" "112"
* 1: "blue" "34"
* 2: "green" "banana"
*/
void getPairs(const XML_Node& node, vector<string>& key,
vector<string>& val) {
vector<string> v;
getStringArray(node, v);
int n = static_cast<int>(v.size());
string::size_type icolon;
for (int i = 0; i < n; i++) {
icolon = v[i].find(":");
if (icolon == string::npos) {
throw CanteraError("getPairs","Missing a colon in the Pair entry ("
+v[i]+")");
}
key.push_back(v[i].substr(0,icolon));
val.push_back(v[i].substr(icolon+1, v[i].size()));
//cout << "getPairs: " << key.back() << " " << val.back() << endl;
}
//! This function interprets the value portion of an XML element
//! as a series of "Pairs" separated by white space.
/*!
* Each pair consists of nonwhite-space characters.
* The first ":" found in the pair string is used to separate
* the string into two parts. The first part is called the "key"
* The second part is called the "val".
* String vectors of key[i] and val[i] are returned in the
* argument list.
* Warning: No spaces are allowed in each pair. Quotes are part
* of the string.
* Example: @verbatum
* <xmlNode>
red:112 blue:34
green:banana
</xmlNode> @endverbatum
*
* Returns:
* key val
* 0: "red" "112"
* 1: "blue" "34"
* 2: "green" "banana"
*/
void getPairs(const XML_Node& node, vector<string>& key,
vector<string>& val) {
vector<string> v;
getStringArray(node, v);
int n = static_cast<int>(v.size());
string::size_type icolon;
for (int i = 0; i < n; i++) {
icolon = v[i].find(":");
if (icolon == string::npos) {
throw CanteraError("getPairs","Missing a colon in the Pair entry ("
+v[i]+")");
}
key.push_back(v[i].substr(0,icolon));
val.push_back(v[i].substr(icolon+1, v[i].size()));
//cout << "getPairs: " << key.back() << " " << val.back() << endl;
}
}
/**
* This function interprets the value portion of an XML element

View file

@ -75,21 +75,82 @@ namespace ctml {
void getStringArray(const Cantera::XML_Node& node, std::vector<std::string>& v);
void getStringArray(const std::string& val, std::vector<std::string>& v);
void getMap(const Cantera::XML_Node& node, std::map<std::string, std::string>& m);
void getPairs(const Cantera::XML_Node& node, std::vector<std::string>& key,
std::vector<std::string>& val);
void getMatrixValues(const Cantera::XML_Node& node,
const std::vector<std::string>& keyString1,
const std::vector<std::string>& keyString2,
Cantera::Array2D &returnValues, bool convert = true,
bool matrixSymmetric = false);
void getMap(const Cantera::XML_Node& node, std::map<std::string, std::string>& m);
//! This function interprets the value portion of an XML element
//! as a series of "Pairs" separated by white space.
/*!
* Each pair consists of nonwhite-space characters.
* The first ":" found in the pair string is used to separate
* the string into two parts. The first part is called the "key"
* The second part is called the "val".
* String vectors of key[i] and val[i] are returned in the
* argument list.
* Warning: No spaces are allowed in each pair. Quotes are part
* of the string.
* Example: @verbatum
* <xmlNode>
red:112 blue:34
green:banana
</xmlNode> @endverbatum
*
* Returns:
* key val
* 0: "red" "112"
* 1: "blue" "34"
* 2: "green" "banana"
*/
void getPairs(const Cantera::XML_Node& node, std::vector<std::string>& key,
std::vector<std::string>& val);
void getMatrixValues(const Cantera::XML_Node& node,
const std::vector<std::string>& keyString1,
const std::vector<std::string>& keyString2,
Cantera::Array2D &returnValues, bool convert = true,
bool matrixSymmetric = false);
void getIntegers(const Cantera::XML_Node& node, std::map<std::string,int>& v);
void getFloats(const Cantera::XML_Node& node, std::map<std::string,double>& v,
bool convert=true);
doublereal getFloat(const Cantera::XML_Node& parent, std::string name,
std::string type="");
int getInteger(const Cantera::XML_Node& parent, std::string name);
//! Get a floating-point value from a child element.
/*!
* Returns a double value for the child named 'name' of element 'parent'. If
* 'type' is supplied and matches a known unit type, unit
* conversion to SI will be done if the child element has an attribute
* 'units'.
*
* Note, it's an error for the child element not to exist.
*
* Example:
*
* Code snipet:
* @verbatum
const XML_Node &State_XMLNode;
doublereal pres = OneAtm;
if (state_XMLNode.hasChild("pressure")) {
pres = getFloat(State_XMLNode, "pressure", "toSI");
}
@endverbatum
*
* reads the corresponding XML file:
* @verbatum
<state>
<pressure units="Pa"> 101325.0 </pressure>
<\state>
@endverbatum
*
* @param parent reference to the XML_Node object of the parent XML element
* @param name Name of the XML child element
* @param type String type. Currently known types are "toSI" and "actEnergy",
* and "" , for no conversion. The default value is "",
* which implies that no conversion is allowed.
*/
doublereal getFloat(const Cantera::XML_Node& parent, std::string name,
std::string type="");
int getInteger(const Cantera::XML_Node& parent, std::string name);
void getStrings(const Cantera::XML_Node& node, std::map<std::string,
std::string>& v);

View file

@ -352,24 +352,24 @@ namespace Cantera {
XML_Node::~XML_Node() {
if (m_locked)
throw CanteraError("XML_Node::~XML_Node",
"attempt to delete locked XML_Node "+name());
int n = static_cast<int>(m_children.size());
for (int i = 0; i < n; i++) {
if (m_children[i]) {
if (m_children[i]->parent() == this) {
delete m_children[i];
m_children[i] = 0;
}
}
}
XML_Node::~XML_Node() {
if (m_locked)
throw CanteraError("XML_Node::~XML_Node",
"attempt to delete locked XML_Node "+name());
int n = static_cast<int>(m_children.size());
for (int i = 0; i < n; i++) {
if (m_children[i]) {
if (m_children[i]->parent() == this) {
delete m_children[i];
m_children[i] = 0;
}
}
}
}
void XML_Node::addComment(string comment) {
addChild("comment",comment);
}
void XML_Node::addComment(string comment) {
addChild("comment",comment);
}
XML_Node& XML_Node::addChild(XML_Node& node) {
m_children.push_back(&node);
@ -400,6 +400,45 @@ namespace Cantera {
if (hasAttrib("id")) return attrib("id");
return std::string("");
}
// The operator[] is overloaded to provide a lookup capability
// on attributes for the current XML element.
/*
* For example
* xmlNode["id"]
* will return the value of the attribute "id" for the current
* XML element. It will return the blank std::string if there isn't
* an attribute with that name.
*
* @param attr attribute string to look up
*
* @return Returns a string representing the value of the attribute
* within the XML node. If there is no attribute
* with the given name, it returns the null string.
*/
std::string XML_Node::operator[](std::string attr) const {
return attrib(attr);
}
// Function returns the value of an attribute
/*
* This function searches the attibutes vector for the parameter
* std::string attribute. If a match is found, the attribute value
* is returned as a string. If no match is found, the empty string
* is returned.
*
* @param attr Std::String containing the attribute to be searched for.
*
* @return Returns If a match is found, the attribute value
* is returned as a string. If no match is found, the empty string
* is returned.
*/
std::string XML_Node::attrib(std::string attr) const {
std::map<std::string,std::string>::const_iterator i = m_attribs.find(attr);
if (i != m_attribs.end()) return i->second;
return "";
}
/**
* This routine carries out a search for an XML node based
@ -636,25 +675,25 @@ namespace Cantera {
}
}
void XML_Node::copy(XML_Node *node_dest) const {
XML_Node *sc, *dc;
int ndc;
node_dest->addValue(m_value);
if (m_name == "") return;
map<string,string>::const_iterator b = m_attribs.begin();
for (; b != m_attribs.end(); ++b) {
node_dest->addAttribute(b->first, b->second);
}
const vector<XML_Node*> &vsc = node_dest->children();
for (int n = 0; n < m_nchildren; n++) {
sc = m_children[n];
ndc = node_dest->nChildren();
(void) node_dest->addChild(sc->name());
dc = vsc[ndc];
sc->copy(dc);
}
void XML_Node::copy(XML_Node *node_dest) const {
XML_Node *sc, *dc;
int ndc;
node_dest->addValue(m_value);
if (m_name == "") return;
map<string,string>::const_iterator b = m_attribs.begin();
for (; b != m_attribs.end(); ++b) {
node_dest->addAttribute(b->first, b->second);
}
const vector<XML_Node*> &vsc = node_dest->children();
for (int n = 0; n < m_nchildren; n++) {
sc = m_children[n];
ndc = node_dest->nChildren();
(void) node_dest->addChild(sc->name());
dc = vsc[ndc];
sc->copy(dc);
}
}
void XML_Node::getChildren(string nm,
vector<XML_Node*>& children) const {

View file

@ -156,23 +156,22 @@ namespace Cantera {
* within the XML node. If there is no attribute
* with the given name, it returns the null string.
*/
std::string operator[](std::string attr) const {
return attrib(attr);
}
std::string operator[](std::string attr) const;
/**
//! Function returns the value of an attribute
/*!
* This function searches the attibutes vector for the parameter
* std::string attribute. If a match is found, the attribute value
* is returned as a string. If no match is found, the empty string
* is returned.
*
* @param(attr) Std::String containing the attribute to be searched for.
* @param attr Std::String containing the attribute to be searched for.
*
* @return Returns If a match is found, the attribute value
* is returned as a string. If no match is found, the empty string
* is returned.
*/
std::string attrib(std::string attr) const {
std::map<std::string,std::string>::const_iterator i = m_attribs.find(attr);
if (i != m_attribs.end()) return i->second;
return "";
}
std::string attrib(std::string attr) const;
std::map<std::string,std::string>& attribs() { return m_attribs; }
XML_Node* parent() const { return m_parent; }
@ -187,6 +186,13 @@ namespace Cantera {
bool hasChild(const std::string ch) const {
return (m_childindex.find(ch) != m_childindex.end());
}
//! Tests whether the current node has an attribute with a particular name
/*!
* @param a Name of the attribute to test
*
* @return Returns true if the attribute exists, false otherwise.
*/
bool hasAttrib(std::string a) const {
return (m_attribs.find(a) != m_attribs.end());
}