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