📄 xmlstorage.h
字号:
_cur(other._cur)
{ // don't copy _stack
}
XMLPos(XMLNode* node, const XS_String& name)
: _root(node),
_cur(node)
{
smart_create(name);
}
XMLPos(XMLNode* node, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
: _root(node),
_cur(node)
{
smart_create(name, attr_name, attr_value);
}
XMLPos(const XMLPos& other, const XS_String& name)
: _root(other._root),
_cur(other._cur)
{
smart_create(name);
}
XMLPos(const XMLPos& other, const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
: _root(other._root),
_cur(other._cur)
{
smart_create(name, attr_name, attr_value);
}
/// access to current node
XMLNode& cur()
{
return *_cur;
}
const XMLNode& cur() const
{
return *_cur;
}
/// C++ access to current node
operator const XMLNode*() const {return _cur;}
operator XMLNode*() {return _cur;}
const XMLNode* operator->() const {return _cur;}
XMLNode* operator->() {return _cur;}
const XMLNode& operator*() const {return *_cur;}
XMLNode& operator*() {return *_cur;}
/// attribute access
XS_String get(const XS_String& attr_name) const
{
return _cur->get(attr_name);
}
/// attribute setting
void put(const XS_String& attr_name, const XS_String& value)
{
_cur->put(attr_name, value);
}
/// C++ attribute access
template<typename T> XS_String get(const T& attr_name) const {return (*_cur)[attr_name];}
XS_String& operator[](const XS_String& attr_name) {return (*_cur)[attr_name];}
/// insert children when building tree
void add_down(XMLNode* child)
{
_cur->add_child(child);
go_to(child);
}
/// go back to previous position
bool back()
{
if (!_stack.empty()) {
_cur = _stack.top();
_stack.pop();
return true;
} else
return false;
}
/// go down to first child
bool go_down()
{
XMLNode* node = _cur->get_first_child();
if (node) {
go_to(node);
return true;
} else
return false;
}
/// search for child and go down
bool go_down(const XS_String& name, int n=0)
{
XMLNode* node = _cur->find(name, n);
if (node) {
go_to(node);
return true;
} else
return false;
}
/// move XPath like to position in XML tree
bool go(const char* path);
/// create child nodes using XPath notation and move to the deepest child
bool create_relative(const char* path)
{
XMLNode* node = _cur->create_relative(path);
if (!node)
return false; // invalid path specified
go_to(node);
return true;
}
/// create node and move to it
void create(const XS_String& name)
{
add_down(new XMLNode(name));
}
/// create node if not already existing and move to it
void smart_create(const XS_String& name)
{
XMLNode* node = _cur->find(name);
if (node)
go_to(node);
else
add_down(new XMLNode(name));
}
/// search matching child node identified by key name and an attribute value
void smart_create(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value)
{
XMLNode* node = _cur->find(name, attr_name, attr_value);
if (node)
go_to(node);
else {
node = new XMLNode(name);
add_down(node);
(*node)[attr_name] = attr_value;
}
}
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
/// search for child and go down
bool go_down(const char* name, int n=0)
{
XMLNode* node = _cur->find(name, n);
if (node) {
go_to(node);
return true;
} else
return false;
}
/// create node and move to it
void create(const char* name)
{
add_down(new XMLNode(name));
}
/// create node if not already existing and move to it
void smart_create(const char* name)
{
XMLNode* node = _cur->find(name);
if (node)
go_to(node);
else
add_down(new XMLNode(name));
}
/// search matching child node identified by key name and an attribute value
template<typename T, typename U>
void smart_create(const char* name, const T& attr_name, const U& attr_value)
{
XMLNode* node = _cur->find(name, attr_name, attr_value);
if (node)
go_to(node);
else {
XMLNode* node = new XMLNode(name);
add_down(node);
(*node)[attr_name] = attr_value;
}
}
#endif
XS_String& str() {return *_cur;}
const XS_String& str() const {return *_cur;}
protected:
XMLNode* _root;
XMLNode* _cur;
std::stack<XMLNode*> _stack;
/// go to specified node
void go_to(XMLNode* child)
{
_stack.push(_cur);
_cur = child;
}
};
/// iterator for XML trees
struct const_XMLPos
{
const_XMLPos(const XMLNode* root)
: _root(root),
_cur(root)
{
}
const_XMLPos(const const_XMLPos& other)
: _root(other._root),
_cur(other._cur)
{ // don't copy _stack
}
/// access to current node
const XMLNode& cur() const
{
return *_cur;
}
/// C++ access to current node
operator const XMLNode*() const {return _cur;}
const XMLNode* operator->() const {return _cur;}
const XMLNode& operator*() const {return *_cur;}
/// attribute access
XS_String get(const XS_String& attr_name) const
{
return _cur->get(attr_name);
}
/// C++ attribute access
template<typename T> XS_String get(const T& attr_name) const {return _cur->get(attr_name);}
/// go back to previous position
bool back()
{
if (!_stack.empty()) {
_cur = _stack.top();
_stack.pop();
return true;
} else
return false;
}
/// go down to first child
bool go_down()
{
const XMLNode* node = _cur->get_first_child();
if (node) {
go_to(node);
return true;
} else
return false;
}
/// search for child and go down
bool go_down(const XS_String& name, int n=0)
{
XMLNode* node = _cur->find(name, n);
if (node) {
go_to(node);
return true;
} else
return false;
}
/// move XPath like to position in XML tree
bool go(const char* path);
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
/// search for child and go down
bool go_down(const char* name, int n=0)
{
XMLNode* node = _cur->find(name, n);
if (node) {
go_to(node);
return true;
} else
return false;
}
#endif
const XS_String& str() const {return *_cur;}
protected:
const XMLNode* _root;
const XMLNode* _cur;
std::stack<const XMLNode*> _stack;
/// go to specified node
void go_to(const XMLNode* child)
{
_stack.push(_cur);
_cur = child;
}
};
/// type converter for boolean data
struct XMLBool
{
XMLBool(bool value=false)
: _value(value)
{
}
XMLBool(LPCXSSTR value, bool def=false)
{
if (value && *value)
_value = !XS_icmp(value, XS_TRUE);
else
_value = def;
}
XMLBool(const XMLNode* node, const XS_String& attr_name, bool def=false)
{
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = !XS_icmp(value.c_str(), XS_TRUE);
else
_value = def;
}
operator bool() const
{
return _value;
}
bool operator!() const
{
return !_value;
}
operator LPCXSSTR() const
{
return _value? XS_TRUE: XS_FALSE;
}
protected:
bool _value;
private:
void operator=(const XMLBool&); // disallow assignment operations
};
/// type converter for boolean data with write access
struct XMLBoolRef
{
XMLBoolRef(XMLNode* node, const XS_String& attr_name, bool def=false)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
operator bool() const
{
return !XS_icmp(_ref.c_str(), XS_TRUE);
}
bool operator!() const
{
return XS_icmp(_ref.c_str(), XS_TRUE)? true: false;
}
XMLBoolRef& operator=(bool value)
{
assign(value);
return *this;
}
void assign(bool value)
{
_ref.assign(value? XS_TRUE: XS_FALSE);
}
void toggle()
{
assign(!operator bool());
}
protected:
XS_String& _ref;
};
/// type converter for integer data
struct XMLInt
{
XMLInt(int value)
: _value(value)
{
}
XMLInt(LPCXSSTR value, int def=0)
{
if (value && *value)
_value = XS_toi(value);
else
_value = def;
}
XMLInt(const XMLNode* node, const XS_String& attr_name, int def=0)
{
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = XS_toi(value.c_str());
else
_value = def;
}
operator int() const
{
return _value;
}
operator XS_String() const
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, _value);
return buffer;
}
protected:
int _value;
private:
void operator=(const XMLInt&); // disallow assignment operations
};
/// type converter for integer data with write access
struct XMLIntRef
{
XMLIntRef(XMLNode* node, const XS_String& attr_name, int def=0)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMLIntRef& operator=(int value)
{
assign(value);
return *this;
}
operator int() const
{
return XS_toi(_ref.c_str());
}
void assign(int value)
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_INTFMT, value);
_ref.assign(buffer);
}
protected:
XS_String& _ref;
};
/// type converter for numeric data
struct XMLDouble
{
XMLDouble(double value)
: _value(value)
{
}
XMLDouble(LPCXSSTR value, double def=0.)
{
LPTSTR end;
if (value && *value)
_value = XS_tod(value, &end);
else
_value = def;
}
XMLDouble(const XMLNode* node, const XS_String& attr_name, double def=0.)
{
LPTSTR end;
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = XS_tod(value.c_str(), &end);
else
_value = def;
}
operator double() const
{
return _value;
}
operator XS_String() const
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, _value);
return buffer;
}
protected:
double _value;
private:
void operator=(const XMLDouble&); // disallow assignment operations
};
/// type converter for numeric data with write access
struct XMLDoubleRef
{
XMLDoubleRef(XMLNode* node, const XS_String& attr_name, double def=0.)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMLDoubleRef& operator=(double value)
{
assign(value);
return *this;
}
operator double() const
{
LPTSTR end;
return XS_tod(_ref.c_str(), &end);
}
void assign(double value)
{
XS_CHAR buffer[32];
XS_snprintf(buffer, COUNTOF(buffer), XS_FLOATFMT, value);
_ref.assign(buffer);
}
protected:
XS_String& _ref;
};
/// type converter for string data
struct XMLString
{
XMLString(const XS_String& value)
: _value(value)
{
}
XMLString(LPCXSSTR value, LPCXSSTR def=XS_EMPTY)
{
if (value && *value)
_value = value;
else
_value = def;
}
XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
{
const XS_String& value = node->get(attr_name);
if (!value.empty())
_value = value;
else
_value = def;
}
operator const XS_String&() const
{
return _value;
}
const XS_String& c_str() const
{
return _value;
}
protected:
XS_String _value;
private:
void operator=(const XMLString&); // disallow assignment operations
};
/// type converter for string data with write access
struct XMStringRef
{
XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
: _ref((*node)[attr_name])
{
if (_ref.empty())
assign(def);
}
XMStringRef(XMLNode* node, const XS_String& node_name, const XS_String& attr_name, LPCXSSTR def=XS_EMPTY)
: _ref(node->subvalue(node_name, attr_name))
{
if (_ref.empty())
assign(def);
}
XMStringRef& operator=(const XS_String& value)
{
assign(value);
return *this;
}
operator const XS_String&() const
{
return _ref;
}
void assign(const XS_String& value)
{
_ref.assign(value);
}
protected:
XS_String& _ref;
};
template<typename T>
inline void read_option(T& var, const_XMLPos& cfg, LPCXSSTR key)
{
const XS_String& val = cfg.get(key);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -