xmlstorage.h
字号:
_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;
}
};
// work around GCC's wide string constant bug
#ifdef __GNUC__
extern const LPCXSSTR XS_TRUE;
extern const LPCXSSTR XS_FALSE;
extern const LPCXSSTR XS_NUMBERFMT;
#else
#define XS_TRUE XS_TEXT("true")
#define XS_FALSE XS_TEXT("false")
#define XS_NUMBERFMT XS_TEXT("%d")
#endif
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
};
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;
};
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_sprintf(buffer, XS_NUMBERFMT, _value);
return buffer;
}
protected:
int _value;
private:
void operator=(const XMLInt&); // disallow assignment operations
};
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_sprintf(buffer, XS_NUMBERFMT, value);
_ref.assign(buffer);
}
protected:
XS_String& _ref;
};
struct XMLString
{
XMLString(const XS_String& value)
: _value(value)
{
}
XMLString(LPCXSSTR value, LPCXSSTR def=XS_TEXT(""))
{
if (value && *value)
_value = value;
else
_value = def;
}
XMLString(const XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_TEXT(""))
{
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
};
struct XMStringRef
{
XMStringRef(XMLNode* node, const XS_String& attr_name, LPCXSSTR def=XS_TEXT(""))
: _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_TEXT(""))
: _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);
if (!val.empty())
var = val;
}
template<>
inline void read_option(int& var, const_XMLPos& cfg, LPCXSSTR key)
{
const XS_String& val = cfg.get(key);
if (!val.empty())
var = XS_toi(val.c_str());
}
#ifdef _MSC_VER
#pragma warning(disable: 4355)
#endif
/// XML reader base class
struct XMLReaderBase
{
XMLReaderBase(XMLNode* node)
: _pos(node),
_parser(XML_ParserCreate(NULL))
{
XML_SetUserData(_parser, this);
XML_SetXmlDeclHandler(_parser, XML_XmlDeclHandler);
XML_SetElementHandler(_parser, XML_StartElementHandler, XML_EndElementHandler);
XML_SetDefaultHandler(_parser, XML_DefaultHandler);
_last_tag = TAG_NONE;
}
virtual ~XMLReaderBase()
{
XML_ParserFree(_parser);
}
XML_Status read();
virtual int read_buffer(char* buffer, int len) = 0;
std::string get_position() const
{
int line = XML_GetCurrentLineNumber(_parser);
int column = XML_GetCurrentColumnNumber(_parser);
std::ostringstream out;
out << "(" << line << ") : [column " << column << "]";
return out.str();
}
std::string get_instructions() const {return _instructions;}
XML_Error get_error_code() {return XML_GetErrorCode(_parser);}
std::string get_error_string() const;
protected:
XMLPos _pos;
XML_Parser _parser;
std::string _xml_version;
std::string _encoding;
std::string _instructions;
std::string _content;
enum {TAG_NONE, TAG_START, TAG_END} _last_tag;
static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone);
static void XMLCALL XML_StartElementHandler(void* userData, const XML_Char* name, const XML_Char** atts);
static void XMLCALL XML_EndElementHandler(void* userData, const XML_Char* name);
static void XMLCALL XML_DefaultHandler(void* userData, const XML_Char* s, int len);
};
/// XML file reader
struct XMLReader : public XMLReaderBase
{
XMLReader(XMLNode* node, std::istream& in)
: XMLReaderBase(node),
_in(in)
{
}
/// read XML stream into XML tree below _pos
int read_buffer(char* buffer, int len)
{
if (!_in.good())
return -1;
_in.read(buffer, len);
return _in.gcount();
}
protected:
std::istream& _in;
};
struct XMLHeader
{
XMLHeader(const std::string& xml_version="1.0", const std::string& encoding="UTF-8", const std::string& doctype="")
: _version(xml_version),
_encoding(encoding),
_doctype(doctype)
{
}
void print(std::ostream& out) const
{
out << "<?xml version=\"" << _version << "\" encoding=\"" << _encoding << "\"?>\n";
if (!_doctype.empty())
out << _doctype << '\n';
if (!_additional.empty())
out << _additional << '\n';
}
std::string _version;
std::string _encoding;
std::string _doctype;
std::string _additional;
};
struct XMLDoc : public XMLNode
{
XMLDoc()
: XMLNode(""),
_last_error(XML_ERROR_NONE)
{
}
XMLDoc(LPCTSTR path)
: XMLNode(""),
_last_error(XML_ERROR_NONE)
{
read(path);
}
std::istream& read(std::istream& in)
{
XMLReader reader(this, in);
read(reader);
return in;
}
bool read(LPCTSTR path)
{
tifstream in(path);
XMLReader reader(this, in);
//#if defined(_STRING_DEFINED) && !defined(XS_STRING_UTF8)
// return read(reader, std::string(ANS(path)));
//#else
return read(reader, XS_String(path));
//#endif
}
bool read(XMLReaderBase& reader)
{
XML_Status status = reader.read();
_header._additional = reader.get_instructions();
if (status == XML_STATUS_ERROR) {
std::ostringstream out;
out << "input stream" << reader.get_position() << " " << reader.get_error_string();
_last_error = reader.get_error_code();
_last_error_msg = out.str();
}
return status != XML_STATUS_ERROR;
}
bool read(XMLReaderBase& reader, const std::string& display_path)
{
XML_Status status = reader.read();
_header._additional = reader.get_instructions();
if (status == XML_STATUS_ERROR) {
std::ostringstream out;
out << display_path << reader.get_position() << " " << reader.get_error_string();
_last_error = reader.get_error_code();
_last_error_msg = out.str();
}
return status != XML_STATUS_ERROR;
}
/// write XML stream preserving previous white space and comments
std::ostream& write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
{
_header.print(out);
if (!_children.empty())
_children.front()->write(out);
return out;
}
/// write XML stream with formating
std::ostream& write_formating(std::ostream& out) const
{
return write(out, FORMAT_PRETTY);
}
void write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
{
tofstream out(path);
write(out, mode);
}
void write_formating(LPCTSTR path) const
{
tofstream out(path);
write_formating(out);
}
XMLHeader _header;
XML_Error _last_error;
std::string _last_error_msg;
};
struct XMLMessage : public XMLDoc
{
XMLMessage(const char* name)
: _pos(this)
{
_pos.create(name);
}
XMLPos _pos;
};
} // namespace XMLStorage
#define _XMLSTORAGE_H
#endif // _XMLSTORAGE_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -