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

📄 xmlattrib.cpp

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

#include "xml.h"

CXMLAttrib::CXMLAttrib()
{
	reset();
}

CXMLAttrib::CXMLAttrib(const char *p)
{
	reset();
	const char *s = p;
	xmlSkipAttribName(s);
	const char *t = s;
	xmlSkipBlanks(s);
	if(*s!='=') s = t;
	else
	{
		++s;
		CXMLAttrib::skipValue(s,s+strlen(s));
	}
	if(load(t,s)) assert(false);
}

CXMLAttrib::CXMLAttrib(const CXMLAttrib& a)
{
	reset();
	if(clone(a)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,int val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,bool val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,long val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,unsigned val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,unsigned long val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

CXMLAttrib::CXMLAttrib(const char *name,const char *val)
{
	reset();
	if(setName(name) || setValue(val)) assert(false);
}

void CXMLAttrib::clean()
{
	if(m_val) delete [] m_val;
	if(m_name) delete [] m_name;
	if(m_next) delete m_next;
	reset();
}

CXMLAttrib::~CXMLAttrib()
{
	clean();
}

void CXMLAttrib::free()
{
	if(m_xac) m_xac->saveup(this);
	else delete this;
}

unsigned CXMLAttrib::strBytes() const
{
	assert(m_name);
	unsigned bytes = m_nlen;
	if(m_vlen) bytes += m_vlen + 3;//formal: name='val'
	return bytes;
}

unsigned CXMLAttrib::updateNode(CXMLNode *p)
{
	assert(p && !m_prev);
	unsigned n = 0;
	for(CXMLAttrib *a=this;a;a=a->m_next,++n) a->m_node = p;
	return n;
}

CXMLAttrib* CXMLAttrib::getlastSibling() const
{
	const CXMLAttrib *a = this;
	for(;a->m_next;a=a->m_next);
	return (CXMLAttrib *)a;
}

CXMLAttrib* CXMLAttrib::getFirstSibling() const
{
	const CXMLAttrib *a = this;
	for(;a->m_prev;a=a->m_prev);
	return (CXMLAttrib *)a;
}

int CXMLAttrib::replaceName(const char *name,unsigned len)
{
	if(len)
	{
		assert(len<0xffff);
		if(len>=m_nbs)
		{
			m_nbs = m_nlen = 0;
			if(m_name) delete [] m_name;
			m_name = new char[len+1];
			if(!m_name) return E_OUTOF_MEMORY;
			m_nbs = len + 1;
		}
		memcpy(m_name,name,len);
		m_name[len] = 0;
		m_nlen = len;
	}
	else if(m_name)
	{
		delete [] m_name;
		m_name = 0;
		m_nlen = m_nbs = 0;
	}
	return 0;
}

int CXMLAttrib::replaceValue(const char *val,unsigned len)
{
	if(len)
	{
		assert(len<0xffff);
		if(len>=m_vbs)
		{
			m_vlen = m_vbs = 0;
			if(m_val) delete [] m_val;
			m_val = new char[len+1];
			if(!m_val) return E_OUTOF_MEMORY;
			m_vbs = len + 1;
		}
		memcpy(m_val,val,len);
		m_val[len] = 0;
		m_vlen = len;
	}
	else if(m_val)
	{
		delete [] m_val;
		m_val = 0;
		m_vlen = m_vbs = 0;
	}
	return 0;
}

int CXMLAttrib::setName(const char *p)
{
	assert(p && *p);
	size_t len = strlen(p);
	return replaceName(p,len);
}

int CXMLAttrib::setValue(const char *p)
{
	assert(p && *p);
	size_t len = strlen(p);
	return replaceValue(p,len);
}

int CXMLAttrib::setBoth(const char *name,const char *val)
{
	int e = setName(name);
	if(!e) e = setValue(val);
	return e;
}

int CXMLAttrib::save(FILE *fp) const
{
	assert(m_name && fp);
	if(fwrite(m_name,1,m_nlen,fp)!=m_nlen) return E_XML_SAVE_WRITE;
	if(m_vlen)
	{
		if(fwrite("=\'",1,2,fp)!=2
			|| fwrite(m_val,1,m_vlen,fp)!=m_vlen
			|| fwrite("\'",1,1,fp)!=1) return E_XML_SAVE_WRITE;
	}
	else assert(m_node->getType()==XNT_META && !m_val);
	return 0;
}

char* CXMLAttrib::toStr(char *p) const
{
	assert(m_name && p);
	memcpy(p,m_name,m_nlen);
	p += m_nlen;
	if(m_vlen)
	{
		*p++ = '=';
		*p++ = '\'';
		memcpy(p,m_val,m_vlen);
		p += m_vlen;
		*p++ = '\'';
	}
	else assert(m_node->getType()==XNT_META && !m_val);
	return p;
}

int CXMLAttrib::load(const char*& b,const char *e)
{
	const char *s = b;
	xmlSkipAttribName(s);
	unsigned len = s - b;
	assert(len);
	int err = replaceName(b,len);
	if(err) return err;
	if(*s!='=')
	{
		replaceValue(0,0);
		b = s;
		return E_XML_META_ATTRIB;//regard as valid in meta node
	}
	++s;
	b = s;
	char c = 0;
	if(*s=='"' || *s=='\'') c = *s;
	err = CXMLAttrib::skipValue(s,e);
	if(err) return err;
	len = s - b;
	if(c){assert(len>2);++b;len-=2;}
	assert(len);
	err = replaceValue(b,len);
	b = s;
	return err;
}

CXMLAttrib* CXMLAttrib::load(CXMLAttribCache *xac,const char*& b,const char *e,int *err)
{
	if(err) *err = E_OUTOF_MEMORY;
	CXMLAttrib *a = xac ? xac->reuse() : new CXMLAttrib;
	if(!a)
	{
		if(err && xac && xac->getAllocCount()>=xac->getAllocLimit()) *err = E_BEYOND_LIMIT;
		return 0;
	}
	int r = a->load(b,e);
	if(err) *err = r;
	return a;
}

int CXMLAttrib::skipValue(const char*& b,const char *e)
{
	if(*b!='\'' && *b!='"')
	{
		xmlSkipSymbol(b);
		return 0;
	}
	char c = *b++;
	const char *s = strchr(b,c);
	if(!s || s>e) return E_XML_BAD_VALUE;
	b = s + 1;
	return 0;
}

⌨️ 快捷键说明

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