xmlparser.h

来自「用bcg库编写的java IDE 源码」· C头文件 代码 · 共 864 行 · 第 1/2 页

H
864
字号
#if !defined(XmlParser_H)
#define XmlParser_H

#include "XmlUtil.h"

#include <algorithm>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;



//////////////////////////////////////////////////////////////////////////////
// XmlParserr
//
// Purpose: used to parse a buffer that has xml formatted data

class EDITPADC_CLASS XmlParser
{
public:

	static long _parseid;
	
	// id of parser (for debugging)
	long		_id;

	// provides string interface to buffer
	string		_strParse;

	// parse buffer and offsets of where we are parsing
	char *		_buffer;
	long		_parseLength;

	// current position in parse buffer
	long		_current;

	// tag, attributes and data position information
	long		_firstTagStart;
	long		_firstTagEnd;

	long		_lastTagStart;
	long		_lastTagEnd;

	long		_nameStart;
	long		_nameEnd;
	long		_attrStart;
	long		_attrEnd;
	long		_valueStart;
	long		_valueEnd;


	XmlParser () :
		_strParse()
	{ 
		clear(); 

		// get parser id
		_id = _parseid;

		// next id
		_parseid++;
	}

	// create/release
	bool create ( const char * buffer, long parseStart, long parseEnd )
	{
		// if invalid stop
		if ( !buffer || parseStart < 0 || parseEnd < parseStart )
			return false;

		return create( buffer + parseStart, getLength(parseStart,parseEnd) );
	}	



	bool create ( const char * buffer, long length )
	{
		// if invalid stop
		if ( !buffer || length <= 0 )
			return false;

		// parse buffer and offsets of where we are parsing
		_buffer      = (char *) buffer;
		_parseLength = length;

		// current position in parse buffer
		_current    = 0;

		return true;
	}	

	void release ()
	{

	}

	// cur position methods
	long getCurrent ()
	{
		return _current;
	}

	long getParseLength ()
	{
		return _parseLength;
	}

	long getCurLength ()
	{
		return getOffsetLength(_current);
	}

	long getOffsetLength ( long offset )
	{
		return getLength(offset,_parseLength - 1);
	}


	char * getBufferPos ()
	{
		return _buffer;
	}

	char * getLastBufferPos ()
	{
		return _buffer + _parseLength;
	}

	char * getCurPos ()
	{
		if ( isValid() )
			return _buffer + _current;
		else
			return NULL;
	}

	char * getParseState ( long & parseLength )
	{
		// if not valid stop
		if ( !isValid() )
		{
			parseLength = 0;
			return getCurPos();
		}

		/*
		// if value has length
		if ( getValueLength() > 0 )
		{
			// if value has a tag it must be parsed
			if ( valueHasTag() )
			{
				// get parse length
				parseLength = getValueLength();

				// return ptr to start of value
				return _buffer + _valueStart;
			}
		}
		*/

		// get parse state
		parseLength = getCurLength();

		// get current buffer position
		char * buffer = getCurPos();

		// if last tag is valid
		/*
		if ( hasLastTag() )
		{
			// if current position is in last tag
			// pos then show stop
			if ( getCurPos() >= getLastTagPos() )
			{
				parseLength = 0;
				return getLastBufferPos();
			}
		}
		*/

		return getCurPos();

	}

	// get ref to parse buffer
	string & str ()
	{
		return _strParse;
	}

	// state methods
	void reset ()
	{
		resetTagPositions();
	}

	bool isValid ()
	{
		// if buffer state not valid
		if ( !_buffer || _parseLength <= 0 )
			return false;

		// if cur position not valid
		if ( _current < 0 || _current > _parseLength )
			return false;

		return true;
	}

	void resetTagPositions ( long start=-1 )
	{
		// set tag positions
		_firstTagStart  = start;
		_firstTagEnd	= start;

		_lastTagStart   = start;
		_lastTagEnd	    = start;

		_nameStart	    = start;
		_nameEnd		= start;

		_attrStart      = start;
		_attrEnd        = start;

		_valueStart     = start;
		_valueEnd       = start;
	}
	
	void clear ()
	{
		// parse buffer and offsets of where we are parsing
		_buffer		 = 0;
		_parseLength = 0;

		// current position in parse buffer
		_current	= 0;

		// reset tag positions
		reset();
	}

	// parse methods
	bool parse ( const char * buffer, long parseStart, long parseEnd )
	{
		// if create fails stop
		if ( !create(buffer,parseStart,parseEnd) )
			return false;

		return parse();
	}

	bool parse ( const char * buffer, long parseLength )
	{
		// if create fails stop
		if ( !create(buffer,parseLength) )
			return false;

		return parse();
	}

	bool parse () 
	{
		// init tag position
		_firstTagStart = _current;
		_firstTagEnd   = _current;

		_lastTagStart  = _current;
		_lastTagEnd    = _current;

				     
		// find first tag
		long first = find( idTagLeft, _current );
		if ( first == -1 )
			return false;


		// if find right tag
		long last  = find( idTagRight, first );
		if ( last == -1  )
			return false;

		// set first tag start/end
		_firstTagStart = first;
		_firstTagEnd   = last;

		// now parse name
		if ( !parseName() )
			return false;

		// parse attributes
		parseAttributes();

		// if null tag no data or last tag
		if ( hasNullTag() )
		{
			// update cur position
			_current  = _firstTagEnd + idTagRightLength;

			// done so show success
			return true;
		}		

		// form end tag
		string endTag;
		endTag  = idTagEnd;
		endTag += getName();
		endTag += idTagRight;

		// find last tag
		first = find( endTag, last );
		if ( first == -1 )
			return false;

		// set last tag start/end
		_lastTagStart = first;
		_lastTagEnd   = first + endTag.size();

		// parse the value if not a null tag
		if ( !hasNullTag() )
			parseValue();

		// update cur position
		// we have parsed a tag so look for the start
		// of a new tag, if found set current position
		// to it, else set to last tag
		long pos = find( idTagLeft, _lastTagEnd );
		if ( pos != -1 )
			_current = pos;
		else
			_current = _lastTagEnd;


		return true;
	}

	bool parse ( string & name,
				 string & value,
				 string & attributes,
				 long & current )
	{

		return true;
	}



	// tag search methods

	bool hasNullTag ()
	{
		// get end of first tag
		char * buffer = _buffer + _firstTagEnd - 1;

		// if null tag marker
		if ( *buffer == '/' && *(buffer+1) == '>' )
			return true;
		else
			return false;
	}

	/////////////////////////////////////////////////////////
	// these methods are protected because the state
	// of parsing might not be properly setup, and
	// if that were so then calling these methods
	// would cause errors

protected:

	// name search methods
	bool parseName ()
	{
		// if first tag search failed show failed
		if ( _firstTagStart < 0 ||  _firstTagEnd < 0 ||
			 _firstTagEnd <= _firstTagStart )
		{
			_nameStart = -1;
			_nameEnd   = -1;
			return false;
		}

		// init name start/end position
		_nameStart = _firstTagStart + idTagLeftLength;
		_nameEnd   = _firstTagEnd - 1;

		// if null tag then backup before
		// null tag marker
		if ( hasNullTag() )
			_nameEnd -= 1;

		// check for separator (i.e. there are attributes)
		long last = find(' ',_nameStart, getNameLength());
		if ( last != -1 )
		{
			// there are attributes so backup
			// before attributes
			_nameEnd = last - 1;
		}

		return true;
	}

	bool parseName ( string & name )
	{
		// set name state
		if ( !parseName() )
			return false;

		name = getName();

		return true;
	}

	// attribute search methods
	bool parseAttributes ()
	{
		// init name start/end position
		_attrStart = -1;
		_attrEnd   = -1;

		// if tag or name length invalid stop
		long tagLength  = getTagLength();
		long nameLength = getNameLength();
		if ( tagLength <= 0 || nameLength <= 0 )
			return 0;

		// if the difference in the lengths is
		// less than the length of the left/right marker
		// then no attributes
		long diff = getTagLength() - getNameLength();

⌨️ 快捷键说明

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