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

📄 xml.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
字号:
// Copyright (C) 2001-2005 Open Source Telecom Corporation.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#ifdef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/file.h>#include <cc++/thread.h>#include <cc++/exception.h>#ifndef	CCXX_WITHOUT_EXTRAS#include <cc++/export.h>#endif#include <cc++/xml.h>#ifndef	WIN32#include <syslog.h>#endif#ifdef HAVE_LIBXML#include <libxml/xmlversion.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <libxml/xmlIO.h>#include <cstdarg>#endif// very ugly, but saves a lot of #ifdefs. To understand this, look at// the private members of XMLRPC.#ifndef HAVE_SSTREAM#define strBuf (*oldStrBuf)#endif#ifdef	CCXX_NAMESPACESnamespace ost {#ifdef HAVE_SSTREAMusing std::stringstream;#elseusing std::strstream;#endifusing std::streambuf;using std::ofstream;using std::ostream;using std::clog;using std::endl;using std::ends;using std::ios;#endif#ifdef	HAVE_LIBXMLextern "C" {static void saxCharacters(XMLStream *xml, const unsigned char *text, int unsigned len){	xml->characters(text, len);}static void saxComment(XMLStream *xml, const unsigned char *text){	unsigned len = strlen((const char *)text);	xml->comment(text, len);}static void saxStartDocument(XMLStream *xml){	xml->startDocument();}static void saxEndDocument(XMLStream *xml){	xml->endDocument();}static void saxStartElement(XMLStream *xml, const unsigned char *name, const unsigned char **attributes){	xml->startElement(name, attributes);}static void saxEndElement(XMLStream *xml, const unsigned char *name){	xml->endElement(name);}}#endif#ifndef	HAVE_LIBXMLstatic bool isElement(char c){	return isalnum(c) || c == ':' || c == '-' || c == '.' || c == '_';}void XMLStream::putData(char c){	dbuf[dp++] = c;	if(dp >= sizeof(dbuf))	{		if(ecount)			characters((unsigned char *)dbuf, dp);				dp = 0;	}}void XMLStream::clrData(void){	if(dp && ecount)		characters((unsigned char *)dbuf, dp);	dp = 0;}void XMLStream::parseInit(void){	state = NONE;	dp = 0;	ecount = dcount = 0;}bool XMLStream::parseTag(void){	size_t len = dp;	const char *data = dbuf;	bool end = false, first = false;	const unsigned char *attrib[128];	unsigned attr = 0;	char *ep;	if(*data == '/')	{		while(--len)		{			if(!isElement(*(++data)))				break;		}		if(len)			return false;		dbuf[dp] = 0;		endElement((const unsigned char *)(dbuf + 1));		dp = 0;		--ecount;		if(ecount < 0)			return false;		if(!ecount)			endDocument();		}	else if(*data == '!')	{		dp = 0;		return true; // dtd	}	else if(*data == '?')	{		if(!strnicmp(data, "?xml version=\"", 14))		{			// version info		}		dp = 0;	}	else if(!isElement(*data))		return false;	else	{		end = false;		if(dbuf[dp - 1] == '/')		{			--dp;			end = true;		}		len = 0;		data = dbuf;		while(len < dp)		{			if(!isElement(*data))				break;			++len;			++data;		}		if(len == dp)		{			if(!ecount)				startDocument();			++ecount;			attrib[0] = attrib[1] = NULL;			dbuf[dp] = 0;			startElement((const unsigned char *)dbuf, attrib);			if(end)			{ending:				--ecount;				endElement((const unsigned char *)dbuf);				if(!ecount)					endDocument();			}			dp = 0;			return true;		}		if(!ecount)			startDocument();		++ecount;		// attributes, name is between data and len		for(;;)		{			while(!isElement(dbuf[len]) && len < dp)			{				if(!isspace(dbuf[len]))					return false;				dbuf[len++] = 0;			}			if(len == dp)				break;			attrib[attr++] = (const unsigned char *)(dbuf + len);			while(isElement(dbuf[len]) && len < dp)				++len;			if(len == dp)				return false;			if(dbuf[len] != '=')				return false;				dbuf[len++] = 0;			if(len == dp)			{				attrib[attr++] = (const unsigned char *)"";				break;			}				if(isspace(dbuf[len]))			{				attrib[attr++] = (const unsigned char *)"";				continue;			}			if(dbuf[len] == '\'' || dbuf[len] == '\"')			{				ep = strchr(dbuf + len + 1, dbuf[len]);				if(!ep)					return false;				attrib[attr++] = (const unsigned char *)dbuf + len + 1;				*(ep++) = 0;				len = ep - dbuf;				continue;			}			if(!isElement(dbuf[len]))				return false;			attrib[attr++] = (const unsigned char *)dbuf;			while(isElement(dbuf[len]) && len < dp)				++len;				if(len == dp)			{				dbuf[len] = 0;				break;			}		}		attrib[attr++] = NULL;		attrib[attr++] = NULL;		startElement((const unsigned char *)dbuf, attrib);		if(end)			goto ending;		dp = 0;		return true;	}								return true;}bool XMLStream::parseChunk(const char *data, size_t len){	unsigned char cp;	while(len--)	{		switch(state)		{		case AMP:			if((!dp && *data == '#') || isElement(*data))			{				dbuf[dp++] = *data;				break;			}			if(*data != ';')				return false;			dbuf[dp] = 0;			if(dbuf[0] == '#')				cp = atoi(dbuf + 1);			else if(!stricmp(dbuf, "amp"))				cp = '&';			else if(!stricmp(dbuf, "lt"))				cp = '<';			else if(!stricmp(dbuf, "gt"))				cp = '>';			else if(!stricmp(dbuf, "apos"))				cp = '`';			else if(!stricmp(dbuf, "quot"))				cp = '\"';			else				return false;			characters(&cp, 1);			dp = 0;			state = NONE;			break;			case TAG:			if(*data == '>')			{				state = NONE;				if(!parseTag())					return false;			}			else if(*data == '[' && dp == 7 && !strncmp(dbuf, "![CDATA", 7))			{				state = CDATA;			}			else if(*data == '-' && dp == 2 && !strncmp(dbuf, "!-", 2))			{				state = COMMENT;				dp = 0;			}			else if(*data == '[' && !strncmp(dbuf, "!DOCTYPE ", 9)) 					{				state = DTD;				dp = 0;			}			else				putData(*data);			break;		case COMMENT:			if(*data == '>' && dp >= 2 && !strncmp(&dbuf[dp - 2], "--", 2))			{				dp -= 2;				if(dp)					comment((unsigned char *)dbuf, dp);				dp = 0;				state = NONE;			}			else			{				dbuf[dp++] = *data;				if(dp == sizeof(dbuf))				{					comment((unsigned char *)dbuf, dp);					dp = 0;				}			}			break;		case CDATA:			putData(*data);			if(dp > 2)				if(!strcmp(&dbuf[dp - 3], "]]>"))				{					dp -= 3;					state = NONE;					clrData();				}			break;			case DTD:			if(*data == '<')				++dcount;			else if(*data == '>' && dcount)				--dcount;			else if(*data == '>')				state = NONE;			break;		case NONE:			if(*data == '<')			{				clrData();				state = TAG;			}			else if(ecount && *data == '&')			{				clrData();				state = AMP;			}			else if(ecount)				putData(*data);		}			++data;	}		return true;}#endifbool XMLStream::parse(const char *resource){	bool ret = false;#ifdef	HAVE_LIBXML	xmlParserCtxtPtr xml;	xmlSAXHandler sax;#endif	char buffer[1024];	int res;	if(resource)		if(!open(resource))			return false;#ifdef	HAVE_LIBXML	memset(&sax, 0, sizeof(sax));	sax.startDocument = (startDocumentSAXFunc)&saxStartDocument;	sax.endDocument = (endDocumentSAXFunc)&saxEndDocument;	sax.startElement = (startElementSAXFunc)&saxStartElement;	sax.endElement = (endElementSAXFunc)&saxEndElement;	sax.characters = (charactersSAXFunc)&saxCharacters;	sax.comment = (commentSAXFunc)&saxComment;	xml = xmlCreatePushParserCtxt(&sax, this, NULL, 0, NULL);	if(!xml)		return false;#else	parseInit();#endif#ifdef	HAVE_LIBXML	while((res = read((unsigned char *) buffer, 1024)))		xmlParseChunk(xml, buffer, res, 0);	xmlParseChunk(xml, buffer, 0, 1);	if(xml->wellFormed)		ret = true;	xml->sax = NULL;	xmlFreeParserCtxt(xml);#else	while((res = read((unsigned char *)buffer, 1024)))		ret = parseChunk(buffer, res);#endif	return ret;}XMLRPC::XMLRPC(size_t bufferSize) :XMLStream(){#ifdef HAVE_SSTREAM	// nothing#else	buffer = new char[bufferSize];	oldStrBuf = NULL;	bufSize = bufferSize;#endif}XMLRPC::~XMLRPC(){#ifdef HAVE_SSTREAM	// nothing#else	if(buffer)		delete[] buffer;	if(oldStrBuf)		delete oldStrBuf;#endif	close();}void XMLRPC::invoke(const char *member){#ifdef HAVE_SSTREAM	strBuf.str() = "";#else	buffer[0] = 0;	oldStrBuf = new strstream(buffer,bufSize);#endif	structFlag = reply = fault = false;	array = 0;	strBuf << "<?xml version=\"1.0\"?>" << endl;	strBuf << "<methodCall>" << endl;	strBuf << "<methodName>" << member << "</methodName>" << endl;	strBuf << "<params>" << endl;}void XMLRPC::response(bool f){	reply = true;	structFlag = false;	fault = f;	array = 0;#ifdef HAVE_SSTREAM	// nothing#else	buffer[0] = 0;	oldStrBuf = new strstream(buffer,bufSize);#endif	strBuf << "<?xml version=\"1.0\"?>" << endl;	strBuf << "<methodResponse>" << endl;	if(fault)		strBuf << "<fault>" << endl;	else		strBuf << "<params>" << endl;}void XMLRPC::addMember(const char *name, long value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	begStruct();	strBuf << "<member><name>" << name << "</name>" << endl;	strBuf << "<value><i4>" << value << "</i4></value></member>" << endl;}void XMLRPC::addMember(const char *name, const char *value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	begStruct();	strBuf << "<member><name>" << name << "</name>" << endl;	strBuf << "<value><string>" << value << "</string></value></member>" << endl;}void XMLRPC::addMember(const char *name, bool value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	begStruct();	strBuf << "<member><name>" << name << "</name>" << endl;	strBuf << "<value><boolean>";	if(value)		strBuf << "1";	else		strBuf << "0";	strBuf << "</boolean></value></member>" << endl;}void XMLRPC::addParam(bool value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	endStruct();	if(!fault && !array)		strBuf << "<param>";	strBuf << "<value><boolean>";	if(value)		strBuf << "1";	else		strBuf << "0";	strBuf << "</boolean></value>";	if(!fault && !array)		strBuf << "</param>";	strBuf << endl;}void XMLRPC::addParam(long value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	endStruct();	if(!fault && !array)		strBuf << "<param>";	strBuf << "<value><i4>" << value << "</i4></value>";	if(!fault && !array)		strBuf << "</param>";	strBuf << endl;}void XMLRPC::addParam(const char *value){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	endStruct();	if(!fault && !array)		strBuf << "<param>" << endl;	strBuf << "<value><string>" << value << "</string></value>";	if(!fault && !array)		strBuf << "</param>";	strBuf << endl;}void XMLRPC::begArray(void){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	if(fault) //do not include arrays in fault responses.		return; 	if(!array)		strBuf << "<param>";	array++;	strBuf << "<array><data>" << endl;}void XMLRPC::endArray(void){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return;#endif	if(!array)		return;	strBuf << "</data></array>";	if(!--array)		strBuf << "</param>";	strBuf << endl;}void XMLRPC::begStruct(void){	if(structFlag)		return;	structFlag = true;	if(!fault && !array)		strBuf << "<param>";	strBuf << "<struct><value>" << endl;}void XMLRPC::endStruct(void){	if(!structFlag)		return;	strBuf << "</struct></value>";	if(!fault && !array)		strBuf << "</param>";	strBuf << endl;	structFlag = false;}bool XMLRPC::send(const char *resource){#ifdef HAVE_SSTREAM	// nothing#else	if(!oldStrBuf)		return false;#endif	endStruct();	while(array)	{		strBuf << "</data></array>" << endl;		--array;	}	if(!fault)		strBuf << "</params>" << endl;	if(reply)		strBuf << "</methodResponse>" << endl << ends;	else		strBuf << "</methodCall>" << endl << ends;	bool result;#ifdef HAVE_SSTREAM	result = post(resource, strBuf.str().c_str());	strBuf.str("");#else	delete oldStrBuf;	oldStrBuf = NULL;	result = post(resource, (const char *)buffer);#endif	return result;}bool XMLStream::open(const char *resource){	return true;}void XMLStream::close(void){}Slog::Level XMLStream::getLogging(void){	return Slog::levelCritical;}void XMLStream::comment(const unsigned char *text, size_t len){}void XMLStream::startDocument(void){}void XMLStream::endDocument(void){}#ifdef	CCXX_NAMESPACES}#endif/** EMACS ** * Local variables: * mode: c++ * c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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