Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

PersistNode.cc

Go to the documentation of this file.
00001 //                            Package   : omniIFR
00002 // PersistNode.cc             Created   : 2004/04/29
00003 //                            Author    : Alex Tingle
00004 //
00005 //    Copyright (C) 2004 Alex Tingle.
00006 //
00007 //    This file is part of the omniIFR application.
00008 //
00009 //    omniIFR is free software; you can redistribute it and/or
00010 //    modify it under the terms of the GNU Lesser General Public
00011 //    License as published by the Free Software Foundation; either
00012 //    version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //    omniIFR is distributed in the hope that it will be useful,
00015 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //    Lesser General Public License for more details.
00018 //
00019 //    You should have received a copy of the GNU Lesser General Public
00020 //    License along with this library; if not, write to the Free Software
00021 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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()) // Don't output root node.
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   // get reference to Next node in the path.
00104   PersistNode*& newchild =_child[name.substr(0,pos)];
00105 
00106   if(pos==string::npos) // leaf: add new leaf.
00107   {
00108     if(newchild)
00109         delete newchild; // overwrite old leaf (and its children)
00110     newchild=new PersistNode();
00111     return newchild;
00112   }
00113   else // branch: just add the branch if it's missing, and then recurse.
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   // get reference to Next node in the path.
00125   map<string,PersistNode*>::iterator childpos =_child.find(name.substr(0,pos));
00126   if(childpos!=_child.end())
00127   {
00128     if(pos==string::npos) // leaf: delete leaf.
00129     {
00130       delete childpos->second;
00131       _child.erase(childpos);
00132     }
00133     else // branch: recurse
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(); // eek! bad input data.
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(); // eek! bad input data.
00186   }
00187   // OK
00188   const int len =pos->second.size()/2;
00189   CORBA::Octet* buf =new CORBA::Octet[len]; // Make a buffer of the right size
00190   char str[3];
00191   str[2]='\0';
00192   for(int i=0; i<len; ++i)                  // Fill it
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;                   // don't bother to clear memory.
00201   memstr.put_octet_array(buf,len);          // Copy it into a cdrMemoryStream
00202   delete[] buf; // ?? use auto_ptr
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 } // end namespace Omniifr

Generated on Fri Mar 4 13:03:23 2005 for OmniIFR by  doxygen 1.4.1