⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlstorage.h

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 H
📖 第 1 页 / 共 4 页
字号:
		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
#ifdef XS_USE_XERCES
 : public HandlerBase
#endif
{
#ifdef XS_USE_XERCES

	XMLReaderBase(XMLNode* node, InputSource* source, bool adoptSource=false);
	virtual ~XMLReaderBase();

	void read();

protected:
	SAXParser*	_parser;
	InputSource* _source;
	bool		_deleteSource;

	virtual void XMLDecl(const XMLCh* const versionStr, const XMLCh* const encodingStr,
						 const XMLCh* const standaloneStr, const XMLCh* const actualEncodingStr);

     // Handlers for the SAX DocumentHandler interface
	virtual void setDocumentLocator(const Locator* const locator);
	virtual void startElement(const XMLCh* const name, AttributeList& attributes);
    virtual void endElement(const XMLCh* const name);
    virtual void characters(const XMLCh* const chars, const unsigned int length);
    virtual void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);

     // Handlers for the SAX ErrorHandler interface
    virtual void error(const SAXParseException& e);
    virtual void fatalError(const SAXParseException& e);
	virtual void warning(const SAXParseException& e);
    virtual void resetErrors();

#elif defined(XS_USE_EXPAT) // !XS_USE_XERCES

	XMLReaderBase(XMLNode* node);
	virtual ~XMLReaderBase();

protected:
	XML_Parser	_parser;

	static void XMLCALL XML_XmlDeclHandler(void* userData, const XML_Char* version, const XML_Char* encoding, int standalone=-1);
	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);

	static std::string get_expat_error_string(XML_Error error_code);

#else // XS_USE_EXPAT

	XMLReaderBase(XMLNode* node)
	 :	_pos(node),
		_endl_defined(false),
		_utf8(false)
	{
		_last_tag = TAG_NONE;
	}

	virtual ~XMLReaderBase();

	bool	parse();

#endif

public:
#ifndef XS_USE_XERCES
	void read();

	std::string	get_position() const;
#endif
	const XMLFormat& get_format() const {return _format;}
	const char* get_endl() const {return _endl_defined? _format._endl: "\n";}

	const XMLErrorList& get_errors() const {return _errors;}
	const XMLErrorList& get_warnings() const {return _warnings;}

	void clear_errors() {_errors.clear(); _warnings.clear();}

#ifdef XMLNODE_LOCATION
	const char* _display_path;	// character pointer for fast reference in XMLLocation

#ifdef XS_USE_XERCES
	const Locator* _locator;
#endif

	XMLLocation get_location() const;
#endif

protected:
	XMLPos		_pos;

	std::string _content;		// UTF-8 encoded
	enum {TAG_NONE, TAG_START, TAG_END} _last_tag;

	XMLErrorList _errors;
	XMLErrorList _warnings;

	XMLFormat	_format;
	bool	_endl_defined;

#ifdef XS_USE_XERCES
	//@@
#elif defined(XS_USE_EXPAT)
	virtual int read_buffer(char* buffer, int len) = 0;
#else
	virtual int get() = 0;
	int		eat_endl();

	bool	_utf8;
#endif

	void	finish_read();

	virtual void XmlDeclHandler(const char* version, const char* encoding, int standalone);
	virtual void StartElementHandler(const XS_String& name, const XMLNode::AttributeMap& attributes);
	virtual void EndElementHandler();
#if defined(XS_USE_XERCES) || defined(XS_USE_EXPAT)
	virtual void DefaultHandler(const XML_Char* s, int len);
#else
	virtual void DefaultHandler(const std::string& s);
#endif
};


 /// XML file reader

#ifdef XS_USE_XERCES

struct XercesXMLReader : public XMLReaderBase
{
	XercesXMLReader(XMLNode* node, InputSource* source, bool adoptSource=false)
	 :	XMLReaderBase(node, source, adoptSource)
	{
	}

	XercesXMLReader(XMLNode* node, LPCTSTR path);
	XercesXMLReader(XMLNode* node, const XMLByte* buffer, size_t bytes, const std::string& system_id=std::string());
};

#define XMLReader XercesXMLReader

#elif defined(XS_USE_EXPAT)

struct ExpatXMLReader : public XMLReaderBase
{
	ExpatXMLReader(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;
};

#define XMLReader ExpatXMLReader

#else // XS_USE_XERCES, XS_USE_EXPAT

struct XMLReader : public XMLReaderBase
{
	XMLReader(XMLNode* node, std::istream& in)
	 :	XMLReaderBase(node),
		_in(in)
	{
	}

	 /// read one character from XML stream
	int get()
	{
		return _in.get();
	}

protected:
	std::istream&	_in;
};

#endif // XS_USE_XERCES


#if defined(_MSC_VER) && _MSC_VER<1400

struct fast_ostringbuffer : public std::streambuf
{
	typedef char _E;
	typedef std::char_traits<_E> _Tr;

	explicit fast_ostringbuffer()
		{_Init(0, 0, std::_Noread);}	// optimized for ios::out mode

	virtual ~fast_ostringbuffer()
		{_Tidy();}

	std::string str() const
		{if (pptr() != 0)
			{std::string _Str(pbase(),
				(_Seekhigh<pptr()? pptr(): _Seekhigh) - pbase());
			return _Str;}
		else
			return std::string();}

protected:
	virtual int_type overflow(int_type _C = _Tr::eof())
		{if (_Tr::eq_int_type(_Tr::eof(), _C))
			return _Tr::not_eof(_C);
		else if (pptr() != 0 && pptr() < epptr())
			{*_Pninc() = _Tr::to_char_type(_C);
			return _C;}
		else
			{size_t _Os = gptr() == 0 ? 0 : epptr() - eback();
			size_t _Ns = _Os + _Alsize;
			_E *_P = _Al.allocate(_Ns, (void *)0);
			if (0 < _Os)
				_Tr::copy(_P, eback(), _Os);
			else if (_ALSIZE < _Alsize)
				_Alsize = _ALSIZE;

			if (_Strmode & std::_Allocated)
				_Al.deallocate(eback(), _Os);

			_Strmode |= std::_Allocated;

			if (_Os == 0)
				{_Seekhigh = _P;
				setp(_P, _P + _Ns);
				setg(_P, _P, _P); }
			else
				{_Seekhigh = _Seekhigh - eback() + _P;
				setp(pbase() - eback() + _P, pptr() - eback() + _P, _P + _Ns);
				setg(_P, _P, _P);}
			*_Pninc() = _Tr::to_char_type(_C);

			return _C;}}

	void _Init(const _E *_S, size_t _N, std::_Strstate _M)
		{_Pendsave = 0, _Seekhigh = 0;
		_Alsize = _MINSIZE, _Strmode = _M;
		setg(0, 0, 0);
		setp(0, 0);}

	void _Tidy()
		{if (_Strmode & std::_Allocated)
			_Al.deallocate(eback(), (pptr() != 0 ? epptr() : egptr()) - eback());
		_Seekhigh = 0;
		_Strmode &= ~std::_Allocated;}

private:
	enum {_ALSIZE = 65536/*512*/, _MINSIZE = 32768/*32*/};	// bigger buffer sizes

	_E *_Pendsave, *_Seekhigh;
	int _Alsize;
	std::_Strstate _Strmode;
	std::allocator<_E> _Al;
};

struct fast_ostringstream : public std::iostream
{
	typedef std::iostream super;

	explicit fast_ostringstream()
		: super(&_Sb) {}

	std::string str() const
		{return _Sb.str();}

private:
	fast_ostringbuffer _Sb;
};

#else

typedef std::ostringstream fast_ostringstream;

#endif


 /// XML document holder
struct XMLDoc : public XMLNode
{
	XMLDoc()
	 :	XMLNode("")
	{
	}

	XMLDoc(LPCTSTR path)
	 :	XMLNode("")
	{
		read(path);
	}

#ifdef XS_USE_XERCES
	bool read(LPCTSTR path)
	{
		XMLReader reader(this, path);

#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(const char* buffer, size_t len, const std::string& system_id=std::string())
	{
		XMLReader reader(this, (const XMLByte*)buffer, len, system_id);

		return read(reader, system_id);
	}

#else // XS_USE_XERCES

	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(const char* buffer, size_t len, const std::string& system_id=std::string())
	{
		std::istringstream in(std::string(buffer, len));

		return read(in, system_id);
	}

	bool read(std::istream& in, const std::string& system_id=std::string())
	{
		XMLReader reader(this, in);

		return read(reader, system_id);
	}
#endif // XS_USE_XERCES

	bool read(XMLReaderBase& reader, const std::string& display_path)
	{
#ifdef XMLNODE_LOCATION
		 // make a string copy to handle temporary string objects
		_display_path = display_path;
		reader._display_path = _display_path.c_str();
#endif

		reader.clear_errors();
		reader.read();

		_format = reader.get_format();
		_format._endl = reader.get_endl();

		if (!reader.get_errors().empty()) {
			_errors = reader.get_errors();
			return false;
		}

		return true;
	}

	 /// write XML stream preserving previous white space and comments
	bool write(std::ostream& out, WRITE_MODE mode=FORMAT_SMART) const
	{
		_format.print_header(out, mode!=FORMAT_PLAIN);

		if (_children.size() == 1)
			_children.front()->write(out, _format, mode);
		else if (!_children.empty()) {
			//throw Exception("more than one XML root!");
			return false;
		}

		return out.good();
	}

	 /// write XML stream with formating
	bool write_formating(std::ostream& out) const
	{
		return write(out, FORMAT_PRETTY);
	}

	bool write(LPCTSTR path, WRITE_MODE mode=FORMAT_SMART) const
	{
		tofstream out(path);

		return write(out, mode);
	}

	bool write_formating(LPCTSTR path) const
	{
		tofstream out(path);

		return write_formating(out);
	}

	XMLFormat		_format;
	XMLErrorList	_errors;

#ifdef XMLNODE_LOCATION
	std::string		_display_path;
#endif
};


 /// XML message wrapper
struct XMLMessage : public XMLDoc
{
	XMLMessage(const char* name)
	 :	_pos(this)
	{
		_pos.create(name);
	}

	std::string toString() const
	{
		std::ostringstream out;

		write(out);

		return out.str();
	}

	XMLPos	_pos;

protected:
	XMLMessage()
	 :	_pos(this)
	{
	}
};


 /// helper structure to read XML messages from strings
struct XMLMessageFromString : public XMLMessage
{
	XMLMessageFromString(const std::string& xml_str, const std::string& system_id=std::string())
	{
		read(xml_str.c_str(), xml_str.length(), system_id);
	}
};


 /// Reader for XML Messages
struct XMLMessageReader : public XMLPos
{
	XMLMessageReader(const std::string& xml_str, const std::string& system_id=std::string())
	 :	XMLPos(&_msg)
	{
		_msg.read(xml_str.c_str(), xml_str.length(), system_id);
	}

	const XMLDoc& get_document()
	{
		return _msg;
	}

protected:
	XMLDoc	_msg;
};


 /// on the fly XML writer
struct XMLWriter
{
	XMLWriter(std::ostream& out, const XMLFormat& format=XMLFormat())
	 :	_pofstream(NULL),
		_out(out),
		_format(format)
	{
		format.print_header(_out, false);	// _format._endl is printed in write_pre()
	}

	XMLWriter(LPCTSTR path, const XMLFormat& format=XMLFormat())
	 :	_pofstream(new tofstream(path)),
		_out(*_pofstream),
		_format(format)
	{
		format.print_header(_out, false);	// _format._endl is printed in write_pre()
	}

	~XMLWriter()
	{
		_out << _format._endl;
		delete _pofstream;
	}

	 /// create node and move to it
	void create(const XS_String& name)
	{
		if (!_stack.empty()) {
			StackEntry& last = _stack.top();

			if (last._state < PRE_CLOSED) {
				write_attributes(last);
				close_pre(last);
			}

			++last._children;
		}

		StackEntry entry;
		entry._node_name = name;
		_stack.push(entry);

		write_pre(entry);
	}

	 /// go back to previous position
	bool back()
	{
		if (!_stack.empty()) {
			write_post(_stack.top());

			_stack.pop();
			return true;
		} else
			return false;
	}

	 /// attribute setting
	void put(const XS_String& attr_name, const XS_String& value)
	{
		if (!_stack.empty())
			_stack.top()._attributes[attr_name] = value;
	}

	 /// C++ write access to an attribute
	XS_String& operator[](const XS_String& attr_name)
	{
		if (_stack.empty())
			return s_empty_attr;

		return _stack.top()._attributes[attr_name];
	}

	void set_content(const XS_String& s, bool cdata=false)
	{
		if (!_stack.empty())
			_stack.top()._content = EncodeXMLString(s.c_str(), cdata);
	}

	 // public for access in StackEntry
	enum WRITESTATE {
		NOTHING, /*PRE,*/ ATTRIBUTES, PRE_CLOSED, /*CONTENT,*/ POST
	};

protected:
	tofstream*		_pofstream;
	std::ostream&	_out;
	const XMLFormat&_format;

	typedef XMLNode::AttributeMap AttrMap;

	 /// container for XMLWriter state information
	struct StackEntry {
		XS_String	_node_name;
		AttrMap		_attributes;
		std::string	_content;
		WRITESTATE	_state;
		bool		_children;

		StackEntry() : _state(NOTHING), _children(false) {}
	};

	std::stack<StackEntry> _stack;

	static XS_String s_empty_attr;

	void close_pre(StackEntry& entry)
	{
		_out << '>';

		entry._state = PRE_CLOSED;
	}

	void write_pre(StackEntry& entry)
	{
		if (_format._pretty >= PRETTY_LINEFEED)
			_out << _format._endl;

		if (_format._pretty == PRETTY_INDENT)
			for(size_t i=_stack.size(); --i>0; )
				_out << XML_INDENT_SPACE;

		_out << '<' << EncodeXMLString(entry._node_name);
		//entry._state = PRE;
	}

	void write_attributes(StackEntry& entry)
	{
		for(AttrMap::const_iterator it=entry._attributes.begin(); it!=entry._attributes.end(); ++it)
			_out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";

		entry._state = ATTRIBUTES;
	}

	void write_post(StackEntry& entry)
	{
		if (entry._state < ATTRIBUTES)
			write_attributes(entry);

		if (entry._children || !entry._content.empty()) {
			if (entry._state < PRE_CLOSED)
				close_pre(entry);

			_out << entry._content;
			//entry._state = CONTENT;

			if (_format._pretty>=PRETTY_LINEFEED && entry._content.empty())
				_out << _format._endl;

			if (_format._pretty==PRETTY_INDENT && entry._content.empty())
				for(size_t i=_stack.size(); --i>0; )
					_out << XML_INDENT_SPACE;

			_out << "</" << EncodeXMLString(entry._node_name) << ">";
		} else {
			_out << "/>";
		}

		entry._state = POST;
	}
};


}	// namespace XMLStorage

#define _XMLSTORAGE_H
#endif // _XMLSTORAGE_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -