mirror of
https://github.com/edubart/otclient.git
synced 2025-12-20 23:47:12 +01:00
make otml simpler and easier to use, improve error handling/exceptions
This commit is contained in:
@@ -3,6 +3,5 @@
|
||||
|
||||
#include "otmldocument.h"
|
||||
#include "otmlnode.h"
|
||||
#include "otmlnodeext.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ OTMLDocumentPtr OTMLDocument::parse(const std::string& fileName)
|
||||
{
|
||||
std::stringstream fin;
|
||||
g_resources.loadFile(fileName, fin);
|
||||
return parse(fin, fileName);
|
||||
return parse(fin, g_resources.resolvePath(fileName));
|
||||
}
|
||||
|
||||
OTMLDocumentPtr OTMLDocument::parse(std::istream& in, const std::string& source)
|
||||
@@ -34,8 +34,7 @@ std::string OTMLDocument::emit()
|
||||
|
||||
bool OTMLDocument::save(const std::string& fileName)
|
||||
{
|
||||
setSource(fileName);
|
||||
|
||||
m_source = fileName;
|
||||
return g_resources.saveFile(fileName, emit());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,15 @@ std::string OTMLEmitter::emitNode(const OTMLNodePtr& node, int currentDepth)
|
||||
ss << node->tag();
|
||||
|
||||
// add ':' to if the node is unique or has value
|
||||
if(node->hasValue() || node->isUnique())
|
||||
if(node->hasValue() || node->isUnique() || node->isNull())
|
||||
ss << ":";
|
||||
} else
|
||||
ss << "-";
|
||||
|
||||
// emit node value
|
||||
if(node->hasValue()) {
|
||||
if(node->isNull())
|
||||
ss << " ~";
|
||||
else if(node->hasValue()) {
|
||||
ss << " ";
|
||||
|
||||
std::string value = node->value();
|
||||
@@ -61,7 +63,7 @@ std::string OTMLEmitter::emitNode(const OTMLNodePtr& node, int currentDepth)
|
||||
for(int i=0;i<node->size();++i) {
|
||||
if(currentDepth >= 0 || i != 0)
|
||||
ss << "\n";
|
||||
ss << emitNode(node->at(i), currentDepth+1);
|
||||
ss << emitNode(node->atIndex(i), currentDepth+1);
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
|
||||
@@ -14,9 +14,6 @@ public:
|
||||
virtual const char* what() const throw() { return m_what.c_str(); }
|
||||
|
||||
protected:
|
||||
OTMLException() { }
|
||||
void generateErrorMessage(const OTMLDocumentPtr& doc, const std::string& error, int line);
|
||||
void generateErrorMessage(const OTMLNodePtr& node, const std::string& error);
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
|
||||
@@ -2,157 +2,86 @@
|
||||
#include "otmlemitter.h"
|
||||
#include "otmldocument.h"
|
||||
|
||||
OTMLNode::OTMLNode()
|
||||
OTMLNodePtr OTMLNode::create(std::string tag, bool unique)
|
||||
{
|
||||
m_unique = false;
|
||||
OTMLNodePtr node(new OTMLNode);
|
||||
node->setTag(tag);
|
||||
node->setUnique(unique);
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string OTMLNode::tag() const
|
||||
OTMLNodePtr OTMLNode::create(std::string tag, std::string value)
|
||||
{
|
||||
return m_tag;
|
||||
OTMLNodePtr node(new OTMLNode);
|
||||
node->setTag(tag);
|
||||
node->setValue(value);
|
||||
node->setUnique(true);
|
||||
return node;
|
||||
}
|
||||
|
||||
std::string OTMLNode::value() const
|
||||
bool OTMLNode::hasChildren() const
|
||||
{
|
||||
// ~ is an alias for no value
|
||||
if(m_value == "~")
|
||||
return fw::empty_string;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
int OTMLNode::size() const
|
||||
{
|
||||
return m_childNodes.size();
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::parent() const
|
||||
{
|
||||
return m_parent.lock();
|
||||
}
|
||||
|
||||
const OTMLNodeList& OTMLNode::childNodes() const
|
||||
{
|
||||
return m_childNodes;
|
||||
}
|
||||
|
||||
std::string OTMLNode::source() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
bool OTMLNode::hasTag() const
|
||||
{
|
||||
return !m_tag.empty();
|
||||
}
|
||||
|
||||
bool OTMLNode::hasValue() const
|
||||
{
|
||||
return (!m_value.empty() && m_value != "~");
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChildNodes() const
|
||||
{
|
||||
return size() > 0;
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChild(const std::string& childTag) const
|
||||
{
|
||||
return !!get(childTag);
|
||||
}
|
||||
|
||||
bool OTMLNode::hasChild(int index) const
|
||||
{
|
||||
return !!get(index);
|
||||
}
|
||||
|
||||
bool OTMLNode::isUnique() const
|
||||
{
|
||||
return m_unique;
|
||||
}
|
||||
|
||||
void OTMLNode::setTag(std::string tag)
|
||||
{
|
||||
m_tag = tag;
|
||||
|
||||
// valued nodes that has tags are always unique
|
||||
if(!m_value.empty() && hasTag())
|
||||
setUnique();
|
||||
}
|
||||
|
||||
void OTMLNode::setValue(const std::string& value)
|
||||
{
|
||||
m_value = value;
|
||||
|
||||
// valued nodes that has tags are always unique
|
||||
if(!m_value.empty() && hasTag())
|
||||
setUnique();
|
||||
}
|
||||
|
||||
void OTMLNode::setParent(const OTMLNodePtr& parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
}
|
||||
|
||||
void OTMLNode::setUnique(bool unique)
|
||||
{
|
||||
m_unique = unique;
|
||||
}
|
||||
|
||||
void OTMLNode::setSource(const std::string& source)
|
||||
{
|
||||
m_source = source;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(const std::string& childTag)
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_childNodes) {
|
||||
if(child->tag() == childTag)
|
||||
return child;
|
||||
int count = 0;
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(!child->isNull())
|
||||
count++;
|
||||
}
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with tag '", childTag, "' not found"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(int childIndex)
|
||||
{
|
||||
if(childIndex < size() && childIndex >= 0)
|
||||
return m_childNodes[childIndex];
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node at index '", childIndex, "' not found"));
|
||||
return nullptr;
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::get(const std::string& childTag) const
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_childNodes) {
|
||||
if(child->tag() == childTag)
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(child->tag() == childTag && !child->isNull())
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::get(int childIndex) const
|
||||
OTMLNodePtr OTMLNode::getIndex(int childIndex) const
|
||||
{
|
||||
if(childIndex < size() && childIndex >= 0)
|
||||
return m_childNodes[childIndex];
|
||||
return m_children[childIndex];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::at(const std::string& childTag)
|
||||
{
|
||||
OTMLNodePtr res;
|
||||
for(const OTMLNodePtr& child : m_children) {
|
||||
if(child->tag() == childTag && !child->isNull()) {
|
||||
res = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!res)
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with tag '", childTag, "' not found"));
|
||||
return res;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::atIndex(int childIndex)
|
||||
{
|
||||
if(childIndex >= size() || childIndex < 0)
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("child node with index '", childIndex, "' not found"));
|
||||
return m_children[childIndex];
|
||||
}
|
||||
|
||||
void OTMLNode::addChild(const OTMLNodePtr& newChild)
|
||||
{
|
||||
// replace is needed when the tag is marked as unique
|
||||
if(newChild->hasTag()) {
|
||||
for(OTMLNodePtr node : m_childNodes) {
|
||||
for(const OTMLNodePtr& node : m_children) {
|
||||
if(node->tag() == newChild->tag() && (node->isUnique() || newChild->isUnique())) {
|
||||
newChild->setUnique();
|
||||
newChild->setUnique(true);
|
||||
replaceChild(node, newChild);
|
||||
|
||||
// remove any other child with the same tag
|
||||
auto it = m_childNodes.begin();
|
||||
while(it != m_childNodes.end()) {
|
||||
auto it = m_children.begin();
|
||||
while(it != m_children.end()) {
|
||||
OTMLNodePtr node = (*it);
|
||||
if(node != newChild && node->tag() == newChild->tag()) {
|
||||
node->setParent(nullptr);
|
||||
it = m_childNodes.erase(it);
|
||||
it = m_children.erase(it);
|
||||
} else
|
||||
++it;
|
||||
}
|
||||
@@ -161,60 +90,67 @@ void OTMLNode::addChild(const OTMLNodePtr& newChild)
|
||||
}
|
||||
}
|
||||
|
||||
m_childNodes.push_back(newChild);
|
||||
m_children.push_back(newChild);
|
||||
newChild->setParent(shared_from_this());
|
||||
}
|
||||
|
||||
bool OTMLNode::removeChild(const OTMLNodePtr& oldChild)
|
||||
{
|
||||
for(auto it = m_childNodes.begin(); it != m_childNodes.end(); ++it) {
|
||||
if((*it) == oldChild) {
|
||||
m_childNodes.erase(it);
|
||||
oldChild->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
auto it = std::find(m_children.begin(), m_children.end(), oldChild);
|
||||
if(it != m_children.end()) {
|
||||
m_children.erase(it);
|
||||
oldChild->setParent(nullptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OTMLNode::replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild)
|
||||
{
|
||||
for(auto it = m_childNodes.begin(); it != m_childNodes.end(); ++it) {
|
||||
if((*it) == oldChild) {
|
||||
oldChild->setParent(nullptr);
|
||||
newChild->setParent(shared_from_this());
|
||||
it = m_childNodes.erase(it);
|
||||
m_childNodes.insert(it, newChild);
|
||||
return true;
|
||||
}
|
||||
auto it = std::find(m_children.begin(), m_children.end(), oldChild);
|
||||
if(it != m_children.end()) {
|
||||
oldChild->setParent(nullptr);
|
||||
newChild->setParent(shared_from_this());
|
||||
it = m_children.erase(it);
|
||||
m_children.insert(it, newChild);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OTMLNode::clear()
|
||||
{
|
||||
m_childNodes.clear();
|
||||
}
|
||||
|
||||
void OTMLNode::merge(const OTMLNodePtr& node)
|
||||
{
|
||||
for(const OTMLNodePtr& child : node->childNodes()) {
|
||||
OTMLNodePtr newNode(new OTMLNode);
|
||||
newNode->setUnique(child->isUnique());
|
||||
newNode->setTag(child->tag());
|
||||
newNode->setValue(child->value());
|
||||
addChild(newNode);
|
||||
newNode->merge(child);
|
||||
}
|
||||
for(const OTMLNodePtr& child : node->m_children)
|
||||
addChild(child->clone());
|
||||
setTag(node->tag());
|
||||
setSource(node->source());
|
||||
}
|
||||
|
||||
void OTMLNode::clear()
|
||||
{
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
child->setParent(nullptr);
|
||||
m_children.clear();
|
||||
}
|
||||
|
||||
OTMLNodeList OTMLNode::children() const
|
||||
{
|
||||
OTMLNodeList children;
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
if(!child->isNull())
|
||||
children.push_back(child);
|
||||
return children;
|
||||
}
|
||||
|
||||
OTMLNodePtr OTMLNode::clone() const
|
||||
{
|
||||
OTMLNodePtr myClone(new OTMLNode);
|
||||
myClone->setTag(tag());
|
||||
myClone->setValue(value());
|
||||
myClone->setUnique(isUnique());
|
||||
for(OTMLNodePtr child : childNodes())
|
||||
myClone->setTag(m_tag);
|
||||
myClone->setValue(m_value);
|
||||
myClone->setUnique(m_unique);
|
||||
myClone->setNull(m_null);
|
||||
myClone->setSource(m_source);
|
||||
for(const OTMLNodePtr& child : m_children)
|
||||
myClone->addChild(child->clone());
|
||||
return myClone;
|
||||
}
|
||||
@@ -223,3 +159,4 @@ std::string OTMLNode::emit()
|
||||
{
|
||||
return OTMLEmitter::emitNode(shared_from_this(), 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,214 +2,138 @@
|
||||
#define OTMLNODE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "otmlexception.h"
|
||||
|
||||
class OTMLNode : public std::enable_shared_from_this<OTMLNode>
|
||||
{
|
||||
public:
|
||||
OTMLNode();
|
||||
virtual ~OTMLNode() { }
|
||||
|
||||
std::string value() const;
|
||||
std::string tag() const;
|
||||
int size() const;
|
||||
OTMLNodePtr parent() const;
|
||||
const OTMLNodeList& childNodes() const;
|
||||
std::string source() const;
|
||||
static OTMLNodePtr create(std::string tag = fw::empty_string, bool unique = false);
|
||||
static OTMLNodePtr create(std::string tag, std::string value);
|
||||
|
||||
bool hasTag() const;
|
||||
bool hasValue() const;
|
||||
bool hasChildNodes() const;
|
||||
bool hasChild(const std::string& childTag) const;
|
||||
bool hasChild(int index) const;
|
||||
bool isUnique() const;
|
||||
std::string tag() const { return m_tag; }
|
||||
int size() const { return m_children.size(); }
|
||||
OTMLNodePtr parent() const { return m_parent.lock(); }
|
||||
std::string source() const { return m_source; }
|
||||
|
||||
void setTag(std::string tag);
|
||||
void setValue(const std::string& value);
|
||||
void setParent(const OTMLNodePtr& parent);
|
||||
void setUnique(bool unique = true);
|
||||
void setSource(const std::string& source);
|
||||
bool isUnique() const { return m_unique; }
|
||||
bool isNull() const { return m_null; }
|
||||
|
||||
/// Same as get but if the child node doesn't exist throws an OTMLException
|
||||
OTMLNodePtr at(const std::string& childTag);
|
||||
OTMLNodePtr at(int childIndex);
|
||||
bool hasTag() const { return !m_tag.empty(); }
|
||||
bool hasValue() const { return !m_value.empty(); }
|
||||
bool hasChildren() const;
|
||||
bool hasChildAt(const std::string& childTag) { return !!get(childTag); }
|
||||
bool hasChildAtIndex(int childIndex) { return !!getIndex(childIndex); }
|
||||
|
||||
void setTag(std::string tag) { m_tag = tag; }
|
||||
void setValue(const std::string& value) { m_value = value; }
|
||||
void setNull(bool null) { m_null = null; }
|
||||
void setUnique(bool unique) { m_unique = unique; }
|
||||
void setParent(const OTMLNodePtr& parent) { m_parent = parent; }
|
||||
void setSource(const std::string& source) { m_source = source; }
|
||||
|
||||
/// Get a child node, if doesn't exists returns nullptr
|
||||
OTMLNodePtr get(const std::string& childTag) const;
|
||||
OTMLNodePtr get(int childIndex) const;
|
||||
OTMLNodePtr getIndex(int childIndex) const;
|
||||
|
||||
OTMLNodePtr at(const std::string& childTag);
|
||||
OTMLNodePtr atIndex(int childIndex);
|
||||
|
||||
void addChild(const OTMLNodePtr& newChild);
|
||||
bool removeChild(const OTMLNodePtr& oldChild);
|
||||
bool replaceChild(const OTMLNodePtr& oldChild, const OTMLNodePtr& newChild);
|
||||
|
||||
/// Remove all children
|
||||
void merge(const OTMLNodePtr& node);
|
||||
void clear();
|
||||
|
||||
/// Recursively copy children from another node to this node
|
||||
void merge(const OTMLNodePtr& node);
|
||||
|
||||
/// Recursively clone this node into a new one
|
||||
OTMLNodeList children() const;
|
||||
OTMLNodePtr clone() const;
|
||||
|
||||
/// Emits this node to a std::string
|
||||
virtual std::string emit();
|
||||
|
||||
template<typename T>
|
||||
T read();
|
||||
|
||||
template<typename T>
|
||||
T read(const T& def);
|
||||
|
||||
template<typename T, typename U>
|
||||
T readAt(const U& childIdentifier);
|
||||
|
||||
template<typename T, typename U>
|
||||
T readAt(const U& childIdentifier, const T& def);
|
||||
template<typename T = std::string>
|
||||
T value();
|
||||
template<typename T = std::string>
|
||||
T valueAt(const std::string& childTag);
|
||||
template<typename T = std::string>
|
||||
T valueAtIndex(int childIndex);
|
||||
template<typename T = std::string>
|
||||
T valueAt(const std::string& childTag, const T& def);
|
||||
template<typename T = std::string>
|
||||
T valueAtIndex(int childIndex, const T& def);
|
||||
|
||||
template<typename T>
|
||||
void write(const T& v);
|
||||
|
||||
template<typename T>
|
||||
void writeAt(const std::string& childTag, const T& v);
|
||||
|
||||
template<typename T>
|
||||
void writeIn(const T& v);
|
||||
|
||||
private:
|
||||
virtual std::string emit();
|
||||
|
||||
protected:
|
||||
OTMLNode() : m_unique(false), m_null(false) { }
|
||||
|
||||
OTMLNodeList m_children;
|
||||
OTMLNodeWeakPtr m_parent;
|
||||
std::string m_tag;
|
||||
std::string m_value;
|
||||
std::string m_source;
|
||||
bool m_unique;
|
||||
OTMLNodeList m_childNodes;
|
||||
OTMLNodeWeakPtr m_parent;
|
||||
bool m_null;
|
||||
};
|
||||
|
||||
// templates for reading values
|
||||
#include "otmlexception.h"
|
||||
|
||||
template<typename T>
|
||||
T OTMLNode::read() {
|
||||
T v;
|
||||
if(!from_otmlnode(shared_from_this(), v))
|
||||
throw OTMLException(shared_from_this(),
|
||||
fw::mkstr("failed to cast node value to type '", fw::demangle_type<T>(), "'"));
|
||||
return v;
|
||||
T OTMLNode::value() {
|
||||
T ret;
|
||||
if(!fw::cast(m_value, ret))
|
||||
throw OTMLException(shared_from_this(), fw::mkstr("failed to cast node value to type '", fw::demangle_type<T>(), "'"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T OTMLNode::read(const T& def) {
|
||||
if(hasValue())
|
||||
return read<T>();
|
||||
T OTMLNode::valueAt(const std::string& childTag) {
|
||||
OTMLNodePtr node = at(childTag);
|
||||
return node->value<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T OTMLNode::valueAtIndex(int childIndex) {
|
||||
OTMLNodePtr node = atIndex(childIndex);
|
||||
return node->value<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T OTMLNode::valueAt(const std::string& childTag, const T& def) {
|
||||
if(OTMLNodePtr node = get(childTag))
|
||||
if(!node->isNull())
|
||||
return node->value<T>();
|
||||
return def;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T OTMLNode::readAt(const U& childIdentifier) {
|
||||
OTMLNodePtr child = at(childIdentifier);
|
||||
return child->read<T>();
|
||||
template<typename T>
|
||||
T OTMLNode::valueAtIndex(int childIndex, const T& def) {
|
||||
if(OTMLNodePtr node = getIndex(childIndex))
|
||||
return node->value<T>();
|
||||
return def;
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
T OTMLNode::readAt(const U& childIdentifier, const T& def) {
|
||||
OTMLNodePtr child = get(childIdentifier);
|
||||
if(!child)
|
||||
return def;
|
||||
return child->read<T>(def);
|
||||
}
|
||||
|
||||
|
||||
// templates for writing values
|
||||
template<typename T>
|
||||
void OTMLNode::write(const T& v) {
|
||||
to_otmlnode(shared_from_this(), v);
|
||||
m_value = fw::safe_cast<std::string>(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void OTMLNode::writeAt(const std::string& childTag, const T& v) {
|
||||
OTMLNodePtr child = get(childTag);
|
||||
bool created = false;
|
||||
if(!child) {
|
||||
child = OTMLNodePtr(new OTMLNode);
|
||||
child->setTag(childTag);
|
||||
child->setUnique();
|
||||
created = true;
|
||||
}
|
||||
child->write<T>(v);
|
||||
if(created)
|
||||
addChild(child);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void OTMLNode::writeIn(const T& v) {
|
||||
OTMLNodePtr child = OTMLNodePtr(new OTMLNode);
|
||||
OTMLNodePtr child = OTMLNode::create(childTag);
|
||||
child->write<T>(v);
|
||||
addChild(child);
|
||||
}
|
||||
|
||||
// templates for casting a node to another type
|
||||
template<typename T>
|
||||
bool from_otmlnode(OTMLNodePtr node, T& v) {
|
||||
return fw::cast(node->value(), v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool from_otmlnode(OTMLNodePtr node, std::vector<T>& v) {
|
||||
v.resize(node->size());
|
||||
for(unsigned i=0;i<node->size();++i)
|
||||
v[i] = node->readAt<T>(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool from_otmlnode(OTMLNodePtr node, std::list<T>& v) {
|
||||
for(unsigned i=0;i<node->size();++i)
|
||||
v.push_back(node->readAt<T>(i));
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename K, typename T>
|
||||
bool from_otmlnode(OTMLNodePtr node, std::map<K, T>& m) {
|
||||
for(int i=0;i<node->size();++i) {
|
||||
K k;
|
||||
if(!fw::cast(node->at(i)->tag(), k))
|
||||
return false;
|
||||
m[k] = node->at(i)->read<T>();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// templates for casting a type to a node
|
||||
template<typename T>
|
||||
void to_otmlnode(OTMLNodePtr node, const T& v) {
|
||||
node->setValue(fw::unsafe_cast<std::string>(v));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void to_otmlnode(OTMLNodePtr node, const std::vector<T>& v) {
|
||||
for(unsigned i=0;i<v.size();++i) {
|
||||
OTMLNodePtr newNode(new OTMLNode);
|
||||
newNode->write(v[i]);
|
||||
node->addChild(newNode);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void to_otmlnode(OTMLNodePtr node, const std::list<T>& v) {
|
||||
for(unsigned i=0;i<v.size();++i) {
|
||||
OTMLNodePtr newNode(new OTMLNode);
|
||||
newNode->write(v[i]);
|
||||
node->addChild(newNode);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename K, typename T>
|
||||
void to_otmlnode(OTMLNodePtr node, const std::map<K, T>& m) {
|
||||
for(auto it = m.begin(); it != m.end(); ++it) {
|
||||
std::string k = fw::unsafe_cast<std::string>(it->first);
|
||||
OTMLNodePtr newNode(new OTMLNode);
|
||||
newNode->setTag(k);
|
||||
newNode->setUnique();
|
||||
newNode->write(it->second);
|
||||
node->addChild(newNode);
|
||||
}
|
||||
void OTMLNode::writeIn(const T& v) {
|
||||
OTMLNodePtr child = OTMLNode::create();
|
||||
child->write<T>(v);
|
||||
addChild(child);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "otmlparser.h"
|
||||
#include "otmldocument.h"
|
||||
#include "otmlexception.h"
|
||||
|
||||
OTMLParser::OTMLParser(OTMLDocumentPtr doc, std::istream& in) :
|
||||
currentDepth(0), currentLine(0),
|
||||
@@ -52,6 +53,9 @@ void OTMLParser::parseLine(std::string line)
|
||||
{
|
||||
int depth = getLineDepth(line);
|
||||
|
||||
if(depth == -1)
|
||||
return;
|
||||
|
||||
// remove line sides spaces
|
||||
boost::trim(line);
|
||||
|
||||
@@ -87,6 +91,7 @@ void OTMLParser::parseNode(const std::string& data)
|
||||
std::string tag;
|
||||
std::string value;
|
||||
std::size_t dotsPos = data.find_first_of(':');
|
||||
int nodeLine = currentLine;
|
||||
|
||||
// node that has no tag and may have a value
|
||||
if(!data.empty() && data[0] == '-') {
|
||||
@@ -150,11 +155,18 @@ void OTMLParser::parseNode(const std::string& data)
|
||||
}
|
||||
|
||||
// create the node
|
||||
OTMLNodePtr node(new OTMLNode);
|
||||
OTMLNodePtr node = OTMLNode::create(tag);
|
||||
|
||||
node->setUnique(dotsPos != std::string::npos);
|
||||
node->setTag(tag);
|
||||
node->setValue(value);
|
||||
node->setSource(doc->source() + ":" + fw::safe_cast<std::string>(currentLine));
|
||||
node->setSource(doc->source() + ":" + fw::unsafe_cast<std::string>(nodeLine));
|
||||
|
||||
// ~ is considered the null value
|
||||
if(value == "~")
|
||||
node->setNull(true);
|
||||
else
|
||||
node->setValue(value);
|
||||
|
||||
currentParent->addChild(node);
|
||||
previousNode = node;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user