📄 xmlattrib.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 + -