欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

xmlstorage.h

一个类似windows
H
第 1 页 / 共 3 页
字号:
			_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 + -