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

📄 xml.cpp

📁 这是和p2p相关的一份源码
💻 CPP
字号:
// ------------------------------------------------// File : xml.cpp// Date: 4-apr-2002// Author: giles// Desc: //		Basic XML parsing/creation //// (c) 2002 peercast.org// ------------------------------------------------// 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.// ------------------------------------------------#include "xml.h"#include "stream.h"#include <stdlib.h>#include <stdarg.h>// ----------------------------------void XML::Node::add(Node *n){	if (!n)		return;	n->parent = this;    if (child)    {    	// has children, add to last sibling        Node *s = child;        while (s->sibling)        	s = s->sibling;        s->sibling = n;    }else{    	// no children yet        child = n;    }}// ---------------------------------inline char nibsToByte(char n1, char n2){	if (n1 >= 'A') n1 = n1-'A'+10;	else n1 = n1-'0';	if (n2 >= 'A') n2 = n2-'A'+10;	else n2 = n2-'0';    return ((n2&0xf)<<4)|(n1&0xf);}// ----------------------------------int XML::Node::getBinaryContent(void *ptr, int size){	char *in = contData;    char *out = (char *)ptr;    int i=0;    while (*in)    {    	if (isWhiteSpace(*in))        {        	in++;        }else        {        	if (i >= size)            	throw StreamException("Too much binary data");	    	out[i++] = nibsToByte(in[0],in[1]);	        in+=2;        }    }    return i;}// ----------------------------------void XML::Node::setBinaryContent(void *ptr, int size){	const char hexTable[] = "0123456789ABCDEF";    const int lineWidth = 1023;	contData = new char[size*2+1+(size/lineWidth)];    char *bp = (char *)ptr;    register char *ap = contData;    for(register int i=0; i<size; i++)    {    	register char c = bp[i];    	*ap++ = hexTable[c&0xf];    	*ap++ = hexTable[(c>>4)&0xf];        if ((i&lineWidth)==lineWidth)	    	*ap++ = '\n';    }    ap[0] = 0;}// ----------------------------------void XML::Node::setContent(const char *n){	contData = strdup(n);}// ----------------------------------void XML::Node::setAttributes(const char *n){    char c;	attrData = strdup(n);    // count maximum amount of attributes    int maxAttr = 0;    bool inWS = true;    int i=0;    while ((c=attrData[i++])!=0)    {    	if (isWhiteSpace(c))        {        	inWS = true;        } else {        	if (inWS)        		maxAttr++;            inWS = false;        }    }    attr = new Attribute[maxAttr];    attr[0].namePos = 0;    attr[0].valuePos = 0;    numAttr=1;    i=0;    // skip until whitespace    while (c=attrData[i++])    	if (isWhiteSpace(c))        	break;    if (!c) return;	// no values    attrData[i-1]=0;    while ((c=attrData[i])!=0)    {    	if (!isWhiteSpace(c))        {        	attr[numAttr].namePos = i;            while (attrData[i])				if (attrData[i++] == '=')                	break;			attrData[i-1] = 0;	// null term. name			if (attrData[i++] != '\"')            	throw StreamException("Bad tag value");            attr[numAttr++].valuePos = i;            while (attrData[i])				if (attrData[i++] == '\"')                	break;			attrData[i-1] = 0;	// null term. value        }else{	        i++;    	}    }}// ----------------------------------XML::Node::Node(const char *fmt,...){	va_list ap;  	va_start(ap, fmt);	char tmp[8192];	vsprintf(tmp,fmt,ap);	setAttributes(tmp);   	va_end(ap);		init();}// ----------------------------------void XML::Node::init(){    parent = sibling = child = NULL;    contData = NULL;    userPtr = NULL;}	// ----------------------------------int XML::Node::findAttrInt(const char *name){	char *v = findAttr(name);    if (!v) return 0;    return atoi(v);}// ----------------------------------int XML::Node::findAttrID(const char *name){	char *v = findAttr(name);    if (!v) return 0;    return strToID(v);}// ----------------------------------char *XML::Node::findAttr(const char *name){	int nlen = strlen(name);	for(int i=1; i<numAttr; i++)    {    	char *an = getAttrName(i);    	if (strncmp(an,name,nlen)==0)        	return getAttrValue(i);    }    return NULL;}// ----------------------------------void XML::Node::write(Stream &out, int level){    int i;#if 0    char tabs[64];    for(i=0; i<level; i++)    	tabs[i] = ' ';    tabs[i] = '\0';    if (level)	    out.write(tabs,i);#endif    char *name = getAttrValue(0);    out.write("<",1);    out.write(name,strlen(name));    for(i=1; i<numAttr; i++)    {	    out.write(" ",1);    	char *at = getAttrName(i);	    out.write(at,strlen(at));	    out.write("=\"",2);        char *av = getAttrValue(i);	    out.write(av,strlen(av));	    out.write("\"",1);    }	if ((!contData) && (!child))	{	    out.write("/>\n",3);	}else	{	    out.write(">\n",2);	    if (contData)		    out.write(contData,strlen(contData));		if (child)	    	child->write(out,level+1);#if 0	    if (level)		    out.write(tabs,strlen(tabs));#endif	    out.write("</",2);	    out.write(name,strlen(name));	    out.write(">\n",2);	}    if (sibling)    	sibling->write(out,level);}// ----------------------------------XML::Node::~Node(){//	LOG("delete %s",getName());	if (contData)    	delete [] contData;    if (attrData)    	delete [] attrData;    if (attr)    	delete [] attr;    Node *n = child;    while (n)    {    	Node *nn = n->sibling;    	delete n;    	n = nn;    }}// ----------------------------------XML::~XML(){	if (root)    	delete root;}// ----------------------------------void XML::write(Stream &out){	if (!root)    	throw StreamException("No XML root");	out.writeLine("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>");    root->write(out,1);}// ----------------------------------void XML::writeCompact(Stream &out){	if (!root)    	throw StreamException("No XML root");	out.writeLine("<?xml ?>");    root->write(out,1);}// ----------------------------------void XML::writeHTML(Stream &out){	if (!root)    	throw StreamException("No XML root");    root->write(out,1);}// ----------------------------------void XML::setRoot(Node *n){	root=n;}// ----------------------------------XML::Node *XML::findNode(const char *n){	if (root)      	return root->findNode(n);	else		return NULL;}// ----------------------------------XML::Node *XML::Node::findNode(const char *name){   	if (strcmp(getName(),name)==0)    	return this;	XML::Node *c = child;	while (c)	{		XML::Node *fn = c->findNode(name);		if (fn)			return fn;		c=c->sibling;	}	return NULL;}// ----------------------------------void XML::read(Stream &in){	const int BUFFER_LEN = 100*1024;	static char buf[BUFFER_LEN];    Node *currNode=NULL;    int tp=0;    while (!in.eof())    {    	char c = in.readChar();        if (c == '<')        {        	if (tp && currNode)	// check for content            {            	buf[tp] = 0;            	currNode->setContent(buf);            }            tp = 0;        	// read to next '>'            while (!in.eof())            {            	c = in.readChar();                if (c == '>')                	break;	        	if (tp >= BUFFER_LEN)    	        	throw StreamException("Tag too long");                buf[tp++] = c;            }            buf[tp]=0;            if (buf[0] == '!')					// comment            {             	// do nothing            }else if (buf[0] == '?')			// doc type            {            	if (strncmp(&buf[1],"xml ",4))                	throw StreamException("Not XML document");            }else if (buf[0] == '/')			// end tag            {            	if (!currNode)                	throw StreamException("Unexpected end tag");            	currNode = currNode->parent;            }else 	// new tag            {	            //LOG("tag: %s",buf);            	bool singleTag = false;                if (buf[tp-1] == '/')		   	// check for single tag                {                	singleTag = true;                    buf[tp-1] = 0;                }                Node *n = new Node(buf);                if (currNode)                	currNode->add(n);                else                	setRoot(n);                if (!singleTag)	                currNode = n;            }            tp = 0;        } else {        	if (tp >= BUFFER_LEN)            	throw StreamException("Content too big");        	buf[tp++] = c;        }    }}

⌨️ 快捷键说明

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