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

📄 xmlconfig.cpp

📁 可移植的xml库。已经在windows和linux上测试通过。只使用C++ Runtine
💻 CPP
字号:
//xmlconfig.cpp

#include "xml.h"

CXMLConfig::CXMLConfig() : m_path(0),m_modified(0),m_root(0),m_plen(0),m_buflen(0)
{
}

CXMLConfig::~CXMLConfig()
{
	if(m_root)
	{
		if(m_modified) saveAs(m_path);
		m_root->free();
		m_root = 0;
		m_modified = false;
	}
	if(m_path)
	{
		delete [] m_path;
		m_path = 0;
		m_plen = m_buflen = 0;
	}
}

int CXMLConfig::close(bool discard,bool nooverwrite)
{
	int e = 0;
	if(m_root)
	{
		if(m_modified && !discard) e = saveAs(m_path,nooverwrite);
		m_root->free();
		m_root = 0;
		m_modified = false;
	}
	if(m_path)
	{
		memset(m_path,0,m_buflen);
		m_plen = 0;
	}
	return e;
}

CXMLNode* CXMLConfig::getDir(const char *dir,const char *var) const
{
	assert(dir && *dir && *dir!=':' && *dir!='/');
	CXMLNode *p = m_root;
	if(!p) return 0;
	unsigned len;
	char buf[128];
	const char *s,*e;
	for(s=dir;p && s;)
	{
		if(var && s>=var) break;
		e = strchr(s,'/');
		if(e)
		{
			len = e - s;
			memcpy(buf,s,len);
			buf[len] = 0;
			++e;
		}
		else
		{
			if(var)
			{
				len = var - s;
				memcpy(buf,s,len);
				buf[len] = 0;
			}
			else
			{
				len = strlen(s);
				memcpy(buf,s,len);
				buf[len] = 0;
			}
		}
		assert(len<sizeof(buf));
		p = p->findNode(buf,len,XNT_TAG);
		s = e;
	}
	return p;
}

const char* CXMLConfig::getVar(const char *path,const char *def) const
{
	CXMLAttrib *a = 0;
	const char *var = strrchr(path,':');
	CXMLNode *p = getDir(path,var);
	if(var) assert(*(var+1));
	if(!p || (var ? !(a=p->findAttrib(var+1,0)) : !p->getChildren())) return def;
	if(!var)
	{
		p = p->getFirstChild();
		if(p->getType()!=XNT_CDATA || p->getNext()) return def;
		return p->getNod();
	}
	else return a->getValue();
}

bool CXMLConfig::getVarBool(const char *path,bool def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return *p=='1';
}

char CXMLConfig::getVarChar(const char *path,char def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return *p;
}

unsigned char CXMLConfig::getVarUChar(const char *path,unsigned char def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return *(unsigned char *)p;
}

short CXMLConfig::getVarShort(const char *path,short def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return (short)atoi(p);
}

unsigned short CXMLConfig::getVarUShort(const char *path,unsigned short def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return (unsigned short)atoi(p);
}

int CXMLConfig::getVarInt(const char *path,int def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return atoi(p);
}

unsigned CXMLConfig::getVarUInt(const char *path,unsigned def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return (unsigned)atoi(p);
}

long CXMLConfig::getVarLong(const char *path,long def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return atol(p);
}

unsigned long CXMLConfig::getVarULong(const char *path,unsigned long def) const
{
	const char *p = getVar(path,0);
	if(!p) return def;
	return (unsigned long)atol(p);
}

CXMLNode* CXMLConfig::createDir(const char *dir,const char *var)
{
	assert(dir && *dir && *dir!=':' && *dir!='/');
	CXMLNode *p = m_root;
	if(!p)
	{
		p = m_prs.allocNode();
		if(!p) return 0;
		if(p->replaceNod("xml",3,0)!=0){p->free();return 0;}
		CXMLAttrib *a = m_prs.allocAttrib();
		if(!a){p->free();return 0;}
		if(a->setBoth("version","1.0")!=0){a->free();p->free();return 0;}
		p->appendAttrib(a);
		p->setType(XNT_META);
		p->setFlags('?');
		p->setDepth(0);
		m_root = p;
		a = 0;
	}
	char buf[128];
	unsigned len;
	CXMLNode *t = 0;
	const char *s,*e;
	for(s=dir;p && s;)
	{
		if(var && s>=var) break;
		e = strchr(s,'/');
		if(e)
		{
			len = e - s;
			memcpy(buf,s,len);
			buf[len] = 0;
			++e;
		}
		else
		{
			if(var)
			{
				len = var - s;
				memcpy(buf,s,len);
				buf[len] = 0;
			}
			else
			{
				len = strlen(s);
				memcpy(buf,s,len);
				buf[len] = 0;
			}
		}
		assert(len<sizeof(buf));
		t = p->findNode(buf,len,XNT_TAG);
		if(!t)
		{
			t = m_prs.allocNode();
			if(!t) return 0;
			if(t->replaceNod(buf,len,m_prs.getCodec())!=0){t->free();return 0;}
			if(p->getType()!=XNT_META)
			{
				t->setDepth(p->getDepth()+1);
				p->appendChild(t);
			}
			else
			{
				t->setDepth(p->getDepth());
				p->appendSibling(t);
			}
			m_modified = true;
		}
		p = t;
		s = e;
	}
	return p;
}

int CXMLConfig::setDir(const char *path,CXMLNode *x)
{
	CXMLNode *p = createDir(path,strrchr(path,':'));
	if(!p) return E_OUTOF_MEMORY;
	CXMLNode *t = p->findChild(x->getNod(),x->getLen());
	if(t)
	{
		t = p->removeChild(*t);
		assert(t);
		t->free();
	}
	p->appendChild(x);
	m_modified = true;
	return 0;
}

int CXMLConfig::setVar(const char *path,bool val)
{
	return setVar(path,val ? "1" : "0");
}

int CXMLConfig::setVar(const char *path,char val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,unsigned char val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,short val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,unsigned short val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,int val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,unsigned val)
{
	char buf[8];
	sprintf(buf,"%x",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,long val)
{
	char buf[8];
	sprintf(buf,"%lx",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,unsigned long val)
{
	char buf[8];
	sprintf(buf,"%lx",val);
	return setVar(path,buf);
}

int CXMLConfig::setVar(const char *path,const char *val,CXMLCodec *c)
{
	const char *var = strrchr(path,':');
	CXMLNode *p = createDir(path,var);
	if(!p) return E_OUTOF_MEMORY;
	if(!var)
	{
		assert(p->getChildren()<=1);
		if(p->getChildren()) assert(p->getFirstChild()->getType()==XNT_CDATA);
		CXMLNode *x = p->removeFirstChild();
		if(!x && !(x=m_prs.allocNode())) return E_OUTOF_MEMORY;
		if(x->setNod(val,c)!=0){x->free();return E_OUTOF_MEMORY;}
		x->setType(XNT_CDATA);
		x->setDepth(p->getDepth()+1);
		p->appendChild(x);
	}
	else
	{
		++var;
		assert(*var);
		assert(p->getType()!=XNT_CDATA && p->getType()!=XNT_META);
		CXMLAttrib *a = p->findAttrib(var,0);
		if(a && !p->removeAttrib(*a)) assert(false);
		if(!a && !(a=m_prs.allocAttrib())) return E_OUTOF_MEMORY;
		if(a->setBoth(var,val)!=0){a->free();return E_OUTOF_MEMORY;}
		p->appendAttrib(a);
	}
	m_modified = true;
	return 0;
}

int CXMLConfig::load(const char *path,CXMLCodec *c)
{
	if(m_root)
	{
		if(m_modified) saveAs(m_path);
		m_root->free();
		m_root = 0;
		m_modified = false;
	}
	m_prs.reset();
	unsigned short len = (unsigned short)strlen(path);
	if(!m_path || m_buflen<=len)
	{
		if(m_path) delete [] m_path;
		m_plen = m_buflen = 0;
		m_path = new char[len+1];
		if(!m_path) return E_OUTOF_MEMORY;
		strcpy(m_path,path);
		m_buflen = len + 1;
		m_plen = len;
	}
	m_prs.setCodec(c);
	m_prs.setLoadComments(true);
	int e = m_prs.domParseFile(&m_root,path);
	if(e) return e;
	return 0;
}

int CXMLConfig::save(bool nooverwrite)
{
	return saveAs(m_path,nooverwrite);
}

int CXMLConfig::saveAs(const char *path,bool nooverwrite)
{
	assert(path);
	if(!m_root) return E_XML_SAVE_EMPTY;
	if(path!=m_path)
	{
		unsigned short len = (unsigned short)strlen(path);
		if(!m_path || m_buflen<=len)
		{
			if(m_path) delete [] m_path;
			m_plen = m_buflen = 0;
			m_path = new char[len+1];
			if(!m_path) return E_OUTOF_MEMORY;
			m_buflen = len + 1;
			m_plen = len;
		}
		strcpy(m_path,path);
	}
	if(nooverwrite)
	{
		_finddata_t fd;
		memset(&fd,0,sizeof(fd));
		long f = _findfirst(m_path,&fd);
		if(f!=-1) _findclose(f);
		if(f!=-1 || fd.size) return E_XML_FILE_EXIST;
	}
	FILE *fp = fopen(m_path,"w");
	if(!fp) return E_XML_SAVE_FILE;
	int e = m_root->save(fp,m_prs.getCodec());
	fclose(fp);
	m_modified = e==0;
	return e;
}

⌨️ 快捷键说明

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