00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PersistNode.h"
00025
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <climits>
00029
00030 namespace OmniEvents {
00031
00032
00033 PersistNode::PersistNode(istream& is)
00034 {
00035 while( readnode(is) ){}
00036 }
00037
00038 PersistNode::~PersistNode()
00039 {
00040 for(map<string,PersistNode*>::iterator i=_child.begin(); i!=_child.end(); ++i)
00041 delete i->second;
00042 }
00043
00044 void PersistNode::output(ostream& os,string name) const
00045 {
00046 if(!name.empty())
00047 {
00048 os<<name<<'\n';
00049 for(map<string,string>::const_iterator i=_attr.begin();
00050 i!=_attr.end();
00051 ++i)
00052 {
00053 os<<" "<<i->first<<"="<<i->second<<'\n';
00054 }
00055 os<<" ;;\n";
00056 name+="/";
00057 }
00058 for(map<string,PersistNode*>::const_iterator i=_child.begin();
00059 i!=_child.end();
00060 ++i)
00061 {
00062 i->second->output(os,name+i->first);
00063 }
00064 }
00065
00066
00067 inline bool PersistNode::readnode(istream& is)
00068 {
00069 PersistNode* node =NULL;
00070 string tok;
00071 while(true)
00072 {
00073 if(!readtoken(is,tok) || tok==";;")
00074 return bool(node);
00075 else if(node)
00076 node->addattr(tok);
00077 else if(tok[0]=='-')
00078 delnode(tok.substr(1));
00079 else
00080 node=addnode(tok);
00081 }
00082 }
00083
00084 inline bool PersistNode::readtoken(istream& is, string& tok)
00085 {
00086 while(is)
00087 {
00088 is>>tok;
00089 if(tok.empty())
00090 break;
00091 if(tok[0]!='#')
00092 return true;
00093 is.ignore(INT_MAX,'\n');
00094 }
00095 return false;
00096 }
00097
00098 PersistNode* PersistNode::addnode(const string& name)
00099 {
00100 string::size_type pos =name.find('/');
00101
00102 PersistNode*& newchild =_child[name.substr(0,pos)];
00103
00104 if(pos==string::npos)
00105 {
00106 if(newchild)
00107 delete newchild;
00108 newchild=new PersistNode();
00109 return newchild;
00110 }
00111 else
00112 {
00113 if(!newchild)
00114 newchild=new PersistNode();
00115 return newchild->addnode(name.substr(pos+1));
00116 }
00117 }
00118
00119 void PersistNode::delnode(const string& name)
00120 {
00121 string::size_type pos =name.find('/');
00122
00123 map<string,PersistNode*>::iterator childpos =_child.find(name.substr(0,pos));
00124 if(childpos!=_child.end())
00125 {
00126 if(pos==string::npos)
00127 {
00128 delete childpos->second;
00129 _child.erase(childpos);
00130 }
00131 else
00132 {
00133 childpos->second->delnode(name.substr(pos+1));
00134 }
00135 }
00136 }
00137
00138 void PersistNode::addattr(const string& keyvalue)
00139 {
00140 string::size_type pos =keyvalue.find('=');
00141 _attr[keyvalue.substr(0,pos)]=(pos==string::npos?"":keyvalue.substr(pos+1));
00142 }
00143
00144 void PersistNode::addattr(const string& key, long value)
00145 {
00146 char buf[64];
00147 sprintf(buf,"%i",value);
00148 _attr[key]=string(buf);
00149 }
00150
00151 bool PersistNode::hasAttr(const string& key) const
00152 {
00153 return( _attr.find(key)!=_attr.end() );
00154 }
00155 string PersistNode::attrString(const string& key, const string& fallback) const
00156 {
00157 map<string,string>::const_iterator pos=_attr.find(key);
00158 if(pos==_attr.end())
00159 return fallback;
00160 else
00161 return pos->second;
00162 }
00163 long PersistNode::attrLong(const string& key, long fallback) const
00164 {
00165 map<string,string>::const_iterator pos=_attr.find(key);
00166 if(pos==_attr.end())
00167 return fallback;
00168 else
00169 return atol(pos->second.c_str());
00170 }
00171 PersistNode* PersistNode::child(const string& key) const
00172 {
00173 map<string,PersistNode*>::const_iterator pos=_child.find(key);
00174 if(pos==_child.end())
00175 return NULL;
00176 else
00177 return pos->second;
00178 }
00179
00180 };