Capabilities.cpp

Go to the documentation of this file.
00001 #include "ace/Capabilities.h"
00002 #include "ace/os_include/os_ctype.h"
00003 #include "ace/OS_Memory.h"
00004 #include "ace/OS_NS_string.h"
00005 
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Capabilities.inl"
00008 #endif /* !__ACE_INLINE__ */
00009 
00010 #include "ace/OS_NS_stdio.h"
00011 
00012 ACE_RCSID (ace,
00013            Capabilities,
00014            "Capabilities.cpp,v 4.26 2006/04/19 19:13:09 jwillemsen Exp")
00015 
00016 
00017 #define ACE_ESC ((ACE_TCHAR)0x1b)
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 ACE_CapEntry::~ACE_CapEntry (void)
00022 {
00023 }
00024 
00025 ACE_Capabilities::ACE_Capabilities (void)
00026   : caps_ ()
00027 {
00028 }
00029 
00030 ACE_Capabilities::~ACE_Capabilities (void)
00031 {
00032   this->resetcaps ();
00033 }
00034 
00035 const ACE_TCHAR *
00036 ACE_Capabilities::parse (const ACE_TCHAR *buf, ACE_TString &cap)
00037 {
00038   while (*buf != ACE_LIB_TEXT ('\0') && *buf != ACE_LIB_TEXT (','))
00039     {
00040       if (*buf == ACE_LIB_TEXT ('\\'))
00041         {
00042           ++buf;
00043           if (*buf == ACE_LIB_TEXT ('E') || *buf == ACE_LIB_TEXT ('e'))
00044             {
00045               cap += ACE_ESC;
00046               ++buf;
00047               continue;
00048             }
00049           else if (*buf == ACE_LIB_TEXT ('r'))
00050             {
00051               cap += ACE_LIB_TEXT ('\r');
00052               ++buf;
00053               continue;
00054             }
00055           else if (*buf == ACE_LIB_TEXT ('n'))
00056             {
00057               cap += ACE_LIB_TEXT ('\n');
00058               ++buf;
00059               continue;
00060             }
00061           else if (*buf == ACE_LIB_TEXT ('t'))
00062             {
00063               cap += ACE_LIB_TEXT ('\t');
00064               ++buf;
00065               continue;
00066             }
00067           else if (*buf == ACE_LIB_TEXT ('\\'))
00068             {
00069               cap += *buf++;
00070               continue;
00071             }
00072           if (isdigit(*buf))
00073             {
00074               // @@ UNICODE Does this work with unicode?
00075               int oc = 0;
00076               for (int i = 0;
00077                    i < 3 && *buf && isdigit (*buf);
00078                    i++)
00079                 oc = oc * 8 + (*buf++ - ACE_LIB_TEXT ('0'));
00080 
00081               cap += (ACE_TCHAR) oc;
00082               continue;
00083             }
00084         }
00085       cap += *buf++;
00086     }
00087   return buf;
00088 }
00089 
00090 const ACE_TCHAR *
00091 ACE_Capabilities::parse (const ACE_TCHAR *buf, int &cap)
00092 {
00093   int n = 0;
00094 
00095   while (*buf && isdigit (*buf))
00096     n = n * 10 + (*buf++ - ACE_LIB_TEXT ('0'));
00097 
00098   cap = n;
00099 
00100   return buf;
00101 }
00102 
00103 void
00104 ACE_Capabilities::resetcaps (void)
00105 {
00106   for (CAPABILITIES_MAP::ITERATOR iter (this->caps_);
00107        !iter.done ();
00108        iter.advance ())
00109     {
00110       CAPABILITIES_MAP::ENTRY *entry = 0;
00111       iter.next (entry);
00112       delete entry->int_id_;
00113     }
00114 
00115   this->caps_.close ();
00116   this->caps_.open ();
00117 }
00118 
00119 int
00120 ACE_Capabilities::fillent (const ACE_TCHAR *buf)
00121 {
00122   this->resetcaps ();
00123   while (*buf)
00124     {
00125       ACE_TString s;
00126       int n;
00127       ACE_TString name;
00128       ACE_CapEntry *ce;
00129 
00130       // Skip blanks
00131       while (*buf && isspace(*buf)) buf++;
00132       // If we get end of line return
00133 
00134       if (*buf == ACE_LIB_TEXT ('\0'))
00135         break;
00136 
00137       if (*buf == ACE_LIB_TEXT ('#'))
00138         {
00139           while (*buf && *buf != ACE_LIB_TEXT ('\n'))
00140             buf++;
00141           if (*buf == ACE_LIB_TEXT ('\n'))
00142             buf++;
00143           continue;
00144         }
00145       while(*buf && *buf != ACE_LIB_TEXT ('=')
00146             && *buf!= ACE_LIB_TEXT ('#')
00147             && *buf != ACE_LIB_TEXT (','))
00148         name += *buf++;
00149 
00150       // If name is null.
00151       switch (*buf)
00152         {
00153         case ACE_LIB_TEXT ('='):
00154           // String property
00155           buf = this->parse (buf + 1, s);
00156           ACE_NEW_RETURN (ce,
00157                           ACE_StringCapEntry (s),
00158                           -1);
00159           if (this->caps_.bind (name, ce) == -1)
00160             {
00161               delete ce;
00162               return -1;
00163             }
00164           break;
00165         case ACE_LIB_TEXT ('#'):
00166           // Integer property
00167           buf = this->parse (buf + 1, n);
00168           ACE_NEW_RETURN (ce,
00169                           ACE_IntCapEntry (n),
00170                           -1);
00171           if (this->caps_.bind (name, ce) == -1)
00172             {
00173               delete ce;
00174               return -1;
00175             }
00176           break;
00177         case ACE_LIB_TEXT (','):
00178           // Boolean
00179           ACE_NEW_RETURN (ce,
00180                           ACE_BoolCapEntry (1),
00181                           -1);
00182           if (this->caps_.bind (name, ce) == -1)
00183             {
00184               delete ce;
00185               return -1;
00186             }
00187           break;
00188         default:
00189           return 0;
00190         }
00191 
00192       if (*buf++ != ACE_LIB_TEXT (','))
00193         return -1;
00194     }
00195 
00196   return 0;
00197 }
00198 
00199 int
00200 ACE_Capabilities::is_entry (const ACE_TCHAR *name, const ACE_TCHAR *line)
00201 {
00202   for (;;)
00203     {
00204       // Skip blanks or irrelevant characters
00205       while (*line && isspace(*line))
00206         ++line;
00207 
00208       // End of line reached
00209       if (*line == ACE_LIB_TEXT ('\0'))
00210         break;
00211 
00212       // Build the entry name
00213       ACE_TString nextname;
00214       while (*line && *line != ACE_LIB_TEXT ('|') && *line != ACE_LIB_TEXT (','))
00215         nextname += *line++;
00216 
00217       // We have found the required entry?
00218       if (ACE_OS::strcmp (nextname.c_str (), name) == 0)
00219         return 1;
00220 
00221       // Skip puntuaction char if neccesary.
00222       if (*line == ACE_LIB_TEXT ('|') || *line == ACE_LIB_TEXT (','))
00223         ++line;
00224       else
00225         {
00226           ACE_DEBUG ((LM_DEBUG,
00227                       ACE_LIB_TEXT ("Invalid entry\n")));
00228           break;
00229         }
00230     }
00231   return 0;
00232 }
00233 
00234 int
00235 ACE_Capabilities::getline (FILE *fp, ACE_TString &line)
00236 {
00237   int ch;
00238 
00239   line.set (0, 0);
00240 
00241   while ((ch = fgetc (fp)) != EOF && ch != ACE_LIB_TEXT ('\n'))
00242     line += (ACE_TCHAR) ch;
00243 
00244   if (ch == EOF && line.length () == 0)
00245     return -1;
00246   else
00247     return 0;
00248 }
00249 
00250 int
00251 ACE_Capabilities::getval (const ACE_TCHAR *keyname, ACE_TString &val)
00252 {
00253   ACE_CapEntry* cap = 0;
00254   if (this->caps_.find (keyname, cap) == -1)
00255     return -1;
00256 
00257   ACE_StringCapEntry *scap =
00258     dynamic_cast<ACE_StringCapEntry *> (cap);
00259   if (scap == 0)
00260     return -1;
00261 
00262   val = scap->getval ();
00263   return 0;
00264 }
00265 
00266 int
00267 ACE_Capabilities::getval (const ACE_TCHAR *keyname, int &val)
00268 {
00269   ACE_CapEntry *cap = 0;
00270   if (this->caps_.find (keyname, cap) == -1)
00271     return -1;
00272 
00273   ACE_IntCapEntry *icap =
00274     dynamic_cast<ACE_IntCapEntry *> (cap);
00275   if (icap != 0)
00276     {
00277       val = icap->getval ();
00278       return 0;
00279     }
00280 
00281   ACE_BoolCapEntry *bcap =
00282     dynamic_cast<ACE_BoolCapEntry *> (cap);
00283 
00284   if (bcap == 0)
00285     return -1;
00286 
00287   val = bcap->getval ();
00288   return 0;
00289 }
00290 
00291 #if !defined (ACE_IS_SPLITTING)
00292 static int
00293 is_empty (const ACE_TCHAR *line)
00294 {
00295   while (*line && isspace (*line))
00296     ++line;
00297 
00298   return *line == ACE_LIB_TEXT ('\0') || *line == ACE_LIB_TEXT ('#');
00299 }
00300 
00301 static int
00302 is_line (const ACE_TCHAR *line)
00303 {
00304   while (*line && isspace (*line))
00305     ++line;
00306 
00307   return *line != ACE_LIB_TEXT ('\0');
00308 }
00309 #endif /* !ACE_IS_SPLITTING */
00310 
00311 int
00312 ACE_Capabilities::getent (const ACE_TCHAR *fname, const ACE_TCHAR *name)
00313 {
00314   FILE *fp = ACE_OS::fopen (fname, ACE_LIB_TEXT ("r"));
00315 
00316   if (fp == 0)
00317     ACE_ERROR_RETURN ((LM_ERROR,
00318                        ACE_LIB_TEXT ("Can't open %s file\n"),
00319                        fname),
00320                       -1);
00321 
00322   int done;
00323   ACE_TString line;
00324 
00325   while (0 == (done = (this->getline (fp, line) == -1))
00326          && is_empty (line.c_str ()))
00327     continue;
00328 
00329   while (!done)
00330     {
00331       ACE_TString newline;
00332       ACE_TString description;
00333 
00334       while (0 == (done = (this->getline (fp, newline) == -1)))
00335         if (is_line (newline.c_str ()))
00336           description += newline;
00337         else
00338           break;
00339 
00340       if (this->is_entry (name, line.c_str()))
00341         {
00342           ACE_OS::fclose (fp);
00343           return this->fillent (description.c_str ());
00344         }
00345 
00346       line = newline;
00347       while (!done && is_empty (line.c_str ()))
00348         done = this->getline (fp, line) == -1;
00349     }
00350 
00351   ACE_OS::fclose (fp);
00352   return -1;
00353 }
00354 
00355 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 09:41:48 2006 for ACE by doxygen 1.3.6