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 "Repository.h"
00027
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030
00031 namespace Omniifr {
00032
00033 const char* PersistNode::_separator ="::";
00034
00035 PersistNode::PersistNode(istream& is)
00036 {
00037 while( readnode(is) ){}
00038 }
00039
00040 PersistNode::~PersistNode()
00041 {
00042 for(map<string,PersistNode*>::iterator i=_child.begin(); i!=_child.end(); ++i)
00043 delete i->second;
00044 }
00045
00046 void PersistNode::output(ostream& os,string name) const
00047 {
00048 if(!name.empty())
00049 {
00050 os<<name<<'\n';
00051 for(map<string,string>::const_iterator i=_attr.begin();
00052 i!=_attr.end();
00053 ++i)
00054 {
00055 os<<" "<<i->first<<"="<<i->second<<'\n';
00056 }
00057 os<<" ;;\n";
00058 name+=_separator;
00059 }
00060 for(map<string,PersistNode*>::const_iterator i=_child.begin();
00061 i!=_child.end();
00062 ++i)
00063 {
00064 i->second->output(os,name+i->first);
00065 }
00066 }
00067
00068
00069 inline bool PersistNode::readnode(istream& is)
00070 {
00071 PersistNode* node =NULL;
00072 string tok;
00073 while(true)
00074 {
00075 if(!readtoken(is,tok) || tok==";;")
00076 return bool(node);
00077 else if(node)
00078 node->addattr(tok);
00079 else if(tok[0]=='-')
00080 delnode(tok.substr(1));
00081 else
00082 node=addnode(tok);
00083 }
00084 }
00085
00086 inline bool PersistNode::readtoken(istream& is, string& tok)
00087 {
00088 while(is)
00089 {
00090 is>>tok;
00091 if(tok.empty())
00092 break;
00093 if(tok[0]!='#')
00094 return true;
00095 is.ignore(INT_MAX,'\n');
00096 }
00097 return false;
00098 }
00099
00100 PersistNode* PersistNode::addnode(const string& name)
00101 {
00102 string::size_type pos =name.find(_separator);
00103
00104 PersistNode*& newchild =_child[name.substr(0,pos)];
00105
00106 if(pos==string::npos)
00107 {
00108 if(newchild)
00109 delete newchild;
00110 newchild=new PersistNode();
00111 return newchild;
00112 }
00113 else
00114 {
00115 if(!newchild)
00116 newchild=new PersistNode();
00117 return newchild->addnode(name.substr(pos+2));
00118 }
00119 }
00120
00121 void PersistNode::delnode(const string& name)
00122 {
00123 string::size_type pos =name.find(_separator);
00124
00125 map<string,PersistNode*>::iterator childpos =_child.find(name.substr(0,pos));
00126 if(childpos!=_child.end())
00127 {
00128 if(pos==string::npos)
00129 {
00130 delete childpos->second;
00131 _child.erase(childpos);
00132 }
00133 else
00134 {
00135 childpos->second->delnode(name.substr(pos+2));
00136 }
00137 }
00138 }
00139
00140 void PersistNode::addattr(const string& keyvalue)
00141 {
00142 string::size_type pos =keyvalue.find('=');
00143 _attr[keyvalue.substr(0,pos)]=(pos==string::npos?"":keyvalue.substr(pos+1));
00144 }
00145
00146 void PersistNode::addattr(const string& key, long value)
00147 {
00148 char buf[64];
00149 sprintf(buf,"%i",value);
00150 _attr[key]=string(buf);
00151 }
00152
00153 bool PersistNode::hasAttr(const string& key) const
00154 {
00155 return( _attr.find(key)!=_attr.end() );
00156 }
00157 string PersistNode::attrString(const string& key, const string& fallback) const
00158 {
00159 map<string,string>::const_iterator pos=_attr.find(key);
00160 if(pos!=_attr.end())
00161 return pos->second;
00162 DB(20,"PersistNode failed to find key: "<<key.c_str()<<" (string)")
00163 return fallback;
00164 }
00165 long PersistNode::attrLong(const string& key, long fallback) const
00166 {
00167 map<string,string>::const_iterator pos=_attr.find(key);
00168 if(pos!=_attr.end())
00169 return ::atol(pos->second.c_str());
00170 DB(20,"PersistNode failed to find key: "<<key.c_str()<<" (long)")
00171 return fallback;
00172 }
00173 cdrMemoryStream PersistNode::attrCdrStream(const string& key) const
00174 {
00175 map<string,string>::const_iterator pos=_attr.find(key);
00176 if(pos==_attr.end())
00177 {
00178 DB(1,"ERROR, missing cdrStream attribute: "<<key.c_str())
00179 return cdrMemoryStream();
00180 }
00181 if(1==pos->second.size()%2)
00182 {
00183 DB(1,"ERROR, cdrStream attribute should have even-number of chars: "
00184 <<key.c_str())
00185 return cdrMemoryStream();
00186 }
00187
00188 const int len =pos->second.size()/2;
00189 CORBA::Octet* buf =new CORBA::Octet[len];
00190 char str[3];
00191 str[2]='\0';
00192 for(int i=0; i<len; ++i)
00193 {
00194 str[0]=pos->second[2*i ];
00195 str[1]=pos->second[2*i+1];
00196 long byte=::strtol(str,NULL,16);
00197 assert(byte>=0 && byte<256);
00198 buf[i]=(CORBA::Octet)byte;
00199 }
00200 cdrMemoryStream memstr;
00201 memstr.put_octet_array(buf,len);
00202 delete[] buf;
00203 return memstr;
00204 }
00205 PersistNode* PersistNode::child(const string& key) const
00206 {
00207 map<string,PersistNode*>::const_iterator pos=_child.find(key);
00208 if(pos==_child.end())
00209 return NULL;
00210 else
00211 return pos->second;
00212 }
00213
00214 void PersistNode::outputCdrMemoryStream(
00215 ostream& os,
00216 cdrMemoryStream& memstr,
00217 const char* prefix
00218 )
00219 {
00220 if(prefix)
00221 os<<prefix;
00222 char buf[3];
00223 CORBA::ULong len(memstr.bufSize());
00224 CORBA::Octet* ptr((CORBA::Octet*)memstr.bufPtr());
00225 for(CORBA::ULong i=0; i<len; ++i)
00226 {
00227 sprintf(buf,"%02x",ptr[i]);
00228 os.write(buf,2);
00229 }
00230 }
00231
00232 void PersistNode::outputIOR(
00233 ostream& os,
00234 CORBA::Object_ptr obj,
00235 const char* prefix
00236 )
00237 {
00238 if(prefix)
00239 os<<prefix;
00240 CORBA::String_var iorstr =
00241 Repository_impl::inst()._orb->object_to_string(obj);
00242 os<<iorstr.in();
00243 }
00244
00245 }