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