Configuration.cpp

Go to the documentation of this file.
00001 // $Id: Configuration.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 #include "ace/Configuration.h"
00003 #include "ace/Auto_Ptr.h"
00004 #include "ace/SString.h"
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_strings.h"
00007 
00008 // Can remove this when import_config and export_config are removed from
00009 // ACE_Configuration. They're deprecated at ACE 5.2.
00010 #include "ace/Configuration_Import_Export.h"
00011 
00012 #if !defined (ACE_LACKS_ACCESS)
00013 #  include "ace/OS_NS_unistd.h"
00014 #endif /* ACE_LACKS_ACCESS */
00015 
00016 #if !defined (__ACE_INLINE__)
00017 #include "ace/Configuration.inl"
00018 #endif /* __ACE_INLINE__ */
00019 
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021 
00022 ACE_Section_Key_Internal::ACE_Section_Key_Internal (void)
00023   : ref_count_ (0)
00024 {
00025 }
00026 
00027 ACE_Section_Key_Internal::~ACE_Section_Key_Internal (void)
00028 {
00029 }
00030 
00031 int
00032 ACE_Section_Key_Internal::add_ref (void)
00033 {
00034   ++ref_count_;
00035   return 0;
00036 }
00037 
00038 int
00039 ACE_Section_Key_Internal::dec_ref (void)
00040 {
00041   if (!--ref_count_)
00042     delete this;
00043   return 0;
00044 }
00045 
00046 ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (void)
00047   : key_ (0)
00048 {
00049 }
00050 
00051 ACE_Configuration_Section_Key::~ACE_Configuration_Section_Key (void)
00052 {
00053   if (key_)
00054     key_->dec_ref ();
00055 }
00056 
00057 ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (ACE_Section_Key_Internal* key)
00058   : key_ (key)
00059 {
00060   if (key_)
00061     key_->add_ref ();
00062 }
00063 
00064 ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (const ACE_Configuration_Section_Key& rhs)
00065   : key_ (rhs.key_)
00066 {
00067   if (key_)
00068     key_->add_ref ();
00069 }
00070 
00071 ACE_Configuration_Section_Key&
00072 ACE_Configuration_Section_Key::operator= (const ACE_Configuration_Section_Key& rhs)
00073 {
00074   if (this != &rhs)
00075     {
00076       if (key_)
00077         key_->dec_ref ();
00078 
00079       key_ = rhs.key_;
00080 
00081       if (key_)
00082         key_->add_ref ();
00083     }
00084   return *this;
00085 }
00086 
00087 //////////////////////////////////////////////////////////////////////////////
00088 
00089 ACE_TCHAR ACE_Configuration::NULL_String_ = '\0';
00090 
00091 ACE_Configuration::ACE_Configuration (void)
00092   : root_ ()
00093 {
00094 }
00095 
00096 ACE_Configuration::~ACE_Configuration (void)
00097 {
00098 }
00099 
00100 ACE_Section_Key_Internal*
00101 ACE_Configuration::get_internal_key (const ACE_Configuration_Section_Key& key)
00102 {
00103   return key.key_;
00104 }
00105 
00106 int
00107 ACE_Configuration::expand_path (const ACE_Configuration_Section_Key& key,
00108                                 const ACE_TString& path_in,
00109                                 ACE_Configuration_Section_Key& key_out,
00110                                 int create)
00111 {
00112   // Make a copy of key
00113   ACE_Configuration_Section_Key current_section = key;
00114   ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> pData (path_in.rep ());
00115   ACE_Tokenizer parser (pData.get ());
00116   parser.delimiter_replace ('\\', '\0');
00117   parser.delimiter_replace ('/', '\0');
00118 
00119   for (ACE_TCHAR *temp = parser.next ();
00120        temp != 0;
00121        temp = parser.next ())
00122     {
00123       // Open the section
00124       if (open_section (current_section,
00125                         temp,
00126                         create,
00127                         key_out))
00128         return -1;
00129 
00130       current_section = key_out;
00131     }
00132 
00133   return 0;
00134 
00135 }
00136 
00137 // import_config and export_config are here for backward compatibility,
00138 // and have been deprecated.
00139 int
00140 ACE_Configuration::export_config (const ACE_TCHAR* filename)
00141 {
00142   ACE_Registry_ImpExp exporter (*this);
00143   return exporter.export_config (filename);
00144 }
00145 
00146 int
00147 ACE_Configuration::import_config (const ACE_TCHAR* filename)
00148 {
00149   ACE_Registry_ImpExp importer (*this);
00150   return importer.import_config (filename);
00151 }
00152 
00153 int
00154 ACE_Configuration::validate_name (const ACE_TCHAR* name, int allow_path)
00155 {
00156   // Invalid character set
00157   const ACE_TCHAR* reject =
00158     allow_path ? ACE_TEXT ("][") : ACE_TEXT ("\\][");
00159 
00160   // Position of the first invalid character or terminating null.
00161   size_t const pos = ACE_OS::strcspn (name, reject);
00162 
00163   // Check if it is an invalid character.
00164   if (name[pos] != ACE_TEXT ('\0'))
00165     {
00166       errno = EINVAL;
00167       return -1;
00168     }
00169 
00170   // The first character can never be a path separator.
00171   if (name[0] == ACE_TEXT ('\\'))
00172     {
00173       errno = EINVAL;
00174       return -1;
00175     }
00176 
00177   // Validate length.
00178   if (pos == 0 || pos > 255)
00179     {
00180       errno = ENAMETOOLONG;
00181       return -1;
00182     }
00183 
00184   return 0;
00185 }
00186 
00187 int
00188 ACE_Configuration::validate_value_name (const ACE_TCHAR* name)
00189 {
00190   if (name == 0 || *name == this->NULL_String_)
00191     return 0;
00192 
00193   return this->validate_name (name);
00194 }
00195 
00196 const ACE_Configuration_Section_Key&
00197 ACE_Configuration::root_section (void) const
00198 {
00199   return root_;
00200 }
00201 
00202 /**
00203  * Determine if the contents of this object is the same as the
00204  * contents of the object on the right hand side.
00205  * Returns 1 (True) if they are equal and 0 (False) if they are not equal
00206  */
00207 bool
00208 ACE_Configuration::operator== (const ACE_Configuration& rhs) const
00209 {
00210   bool rc = true;
00211   int sectionIndex = 0;
00212   ACE_TString sectionName;
00213   ACE_Configuration *nonconst_this = const_cast<ACE_Configuration*> (this);
00214   ACE_Configuration &nonconst_rhs  = const_cast<ACE_Configuration&> (rhs);
00215 
00216   const ACE_Configuration_Section_Key& rhsRoot = rhs.root_section ();
00217   ACE_Configuration_Section_Key rhsSection;
00218   ACE_Configuration_Section_Key thisSection;
00219 
00220   // loop through each section in this object
00221   while ((rc) && (nonconst_this->enumerate_sections (this->root_,
00222                                                      sectionIndex,
00223                                                      sectionName) == 0))
00224     {
00225       // find that section in the rhs object
00226       if (nonconst_rhs.open_section (rhsRoot,
00227                                      sectionName.c_str (),
00228                                      0,
00229                                      rhsSection) != 0)
00230         {
00231           // If the rhs object does not contain the section then we are
00232           // not equal.
00233           rc = false;
00234         }
00235       else if (nonconst_this->open_section (this->root_,
00236                                             sectionName.c_str (),
00237                                             0,
00238                                             thisSection) != 0)
00239         {
00240           // if there is some error opening the section in this object
00241           rc = false;
00242         }
00243       else
00244         {
00245           // Well the sections match
00246           int         valueIndex = 0;
00247           ACE_TString valueName;
00248           VALUETYPE   valueType;
00249           VALUETYPE   rhsType;
00250 
00251           // Enumerate each value in this section
00252           while ((rc) && nonconst_this->enumerate_values (thisSection,
00253                                                           valueIndex,
00254                                                           valueName,
00255                                                           valueType) == 0)
00256             {
00257               // look for the same value in the rhs section
00258               if (nonconst_rhs.find_value (rhsSection,
00259                                            valueName.c_str (),
00260                                            rhsType) != 0)
00261                 {
00262                   // We're not equal if the same value cannot
00263                   // be found in the rhs object.
00264                   rc = false;
00265                 }
00266               else if (valueType != rhsType)
00267                 {
00268                   // we're not equal if the types do not match.
00269                   rc = false;
00270                 }
00271               else
00272                 {
00273                   // finally compare values.
00274                   if (valueType == STRING)
00275                     {
00276                       ACE_TString thisString, rhsString;
00277                       if (nonconst_this->get_string_value (thisSection,
00278                                                            valueName.c_str (),
00279                                                            thisString) != 0)
00280                         {
00281                           // we're not equal if we cannot get this string
00282                           rc = false;
00283                         }
00284                       else if (nonconst_rhs.get_string_value (
00285                                  rhsSection,
00286                                  valueName.c_str (),
00287                                  rhsString) != 0)
00288                         {
00289                           // we're not equal if we cannot get rhs string
00290                           rc = false;
00291                         }
00292                       rc = (thisString == rhsString);
00293                     }
00294                   else if (valueType == INTEGER)
00295                     {
00296                       u_int thisInt = 0;
00297                       u_int rhsInt = 0;
00298                       if (nonconst_this->get_integer_value (
00299                             thisSection,
00300                             valueName.c_str (),
00301                             thisInt) != 0)
00302                         {
00303                           // we're not equal if we cannot get this int
00304                           rc = false;
00305                         }
00306                       else if (nonconst_rhs.get_integer_value (
00307                                  rhsSection,
00308                                  valueName.c_str (),
00309                                  rhsInt) != 0)
00310                         {
00311                           // we're not equal if we cannot get rhs int
00312                           rc = false;
00313                         }
00314                       rc = (thisInt == rhsInt);
00315                     }
00316                   else if (valueType == BINARY)
00317                     {
00318                       void* thisData = 0;
00319                       void* rhsData = 0;
00320                       size_t thisLength = 0;
00321                       size_t rhsLength = 0;
00322                       if (nonconst_this->get_binary_value (thisSection,
00323                                                            valueName.c_str (),
00324                                                            thisData,
00325                                                            thisLength) != 0)
00326                         {
00327                           // we're not equal if we cannot get this data
00328                           rc = false;
00329                         }
00330                       else if (nonconst_rhs.get_binary_value (
00331                                  rhsSection,
00332                                  valueName.c_str (),
00333                                  rhsData,
00334                                  rhsLength) != 0)
00335                         {
00336                           // we're not equal if we cannot get this data
00337                           rc = false;
00338                         }
00339 
00340                       rc = (thisLength == rhsLength);
00341                       // are the length's the same?
00342 
00343                       if (rc)
00344                         {
00345                           unsigned char* thisCharData =
00346                             (unsigned char*)thisData;
00347                           unsigned char* rhsCharData = (unsigned char*)rhsData;
00348                           // yes, then check each element
00349                           for (size_t count = 0;
00350                                (rc) && (count < thisLength);
00351                                count++)
00352                             {
00353                               rc = (* (thisCharData + count) == * (rhsCharData + count));
00354                             }
00355 
00356                           delete [] thisCharData;
00357                           delete [] rhsCharData;
00358                         }// end if the length's match
00359                     }
00360                   // We should never have valueTypes of INVALID, therefore
00361                   // we're not comparing them.  How would we since we have
00362                   // no get operation for invalid types.
00363                   // So, if we have them, we guess they are equal.
00364 
00365                 }// end else if values match.
00366 
00367               ++valueIndex;
00368 
00369             }// end value while loop
00370 
00371           // look in the rhs for values not in this
00372           valueIndex = 0;
00373           while ((rc) && (nonconst_rhs.enumerate_values (rhsSection,
00374                                                          valueIndex,
00375                                                          valueName,
00376                                                          rhsType) == 0))
00377             {
00378               // look for the same value in this section
00379               if (nonconst_this->find_value (thisSection,
00380                                              valueName.c_str (),
00381                                              valueType) != 0)
00382                 {
00383                   // We're not equal if the same value cannot
00384                   // be found in the rhs object.
00385                   rc = false;
00386                 }
00387               ++valueIndex;
00388             }// end while for rhs values not in this.
00389 
00390         }// end else if sections match.
00391 
00392       ++sectionIndex;
00393 
00394     }// end section while loop
00395 
00396   // Finally, make sure that there are no sections in rhs that do not
00397   // exist in this
00398   sectionIndex = 0;
00399   while ((rc)
00400          && (nonconst_rhs.enumerate_sections (rhsRoot,
00401                                               sectionIndex,
00402                                               sectionName) == 0))
00403     {
00404       // find the section in this
00405       if (nonconst_this->open_section (this->root_,
00406                                        sectionName.c_str (),
00407                                        0,
00408                                        thisSection) != 0)
00409         {
00410           // if there is some error opening the section in this object
00411           rc = false;
00412         }
00413       else if (nonconst_rhs.open_section (rhsRoot,
00414                                           sectionName.c_str (),
00415                                           0,
00416                                           rhsSection) != 0)
00417         {
00418           // If the rhs object does not contain the section then we
00419           // are not equal.
00420           rc = false;
00421         }
00422       ++sectionIndex;
00423     }
00424   return rc;
00425 }
00426 
00427 bool
00428 ACE_Configuration::operator!= (const ACE_Configuration& rhs) const
00429 {
00430   return !(*this == rhs);
00431 }
00432 
00433 //////////////////////////////////////////////////////////////////////////////
00434 
00435 #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
00436 
00437 static const int ACE_DEFAULT_BUFSIZE = 256;
00438 
00439 static const ACE_TCHAR *temp_name (const ACE_TCHAR *name)
00440 {
00441   if (name && *name == ACE_Configuration::NULL_String_)
00442     return 0;
00443   return name;
00444 }
00445 
00446 ACE_Section_Key_Win32::ACE_Section_Key_Win32 (HKEY hKey)
00447   : hKey_ (hKey)
00448 {
00449 }
00450 
00451 ACE_Section_Key_Win32::~ACE_Section_Key_Win32 (void)
00452 {
00453   ::RegCloseKey (hKey_);
00454 }
00455 
00456 //////////////////////////////////////////////////////////////////////////////
00457 
00458 bool
00459 ACE_Configuration_Win32Registry::operator== (const ACE_Configuration_Win32Registry &rhs) const
00460 {
00461   ACE_UNUSED_ARG (rhs);
00462   return true;
00463 }
00464 
00465 bool
00466 ACE_Configuration_Win32Registry::operator!= (const ACE_Configuration_Win32Registry &rhs) const
00467 {
00468   ACE_UNUSED_ARG (rhs);
00469   return true;
00470 }
00471 
00472 ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry (HKEY hKey)
00473 {
00474   ACE_Section_Key_Win32 *temp = 0;
00475 
00476   ACE_NEW (temp, ACE_Section_Key_Win32 (hKey));
00477 
00478   root_ = ACE_Configuration_Section_Key (temp);
00479 }
00480 
00481 
00482 ACE_Configuration_Win32Registry::~ACE_Configuration_Win32Registry (void)
00483 {
00484 }
00485 
00486 int
00487 ACE_Configuration_Win32Registry::open_section (const ACE_Configuration_Section_Key& base,
00488                                                const ACE_TCHAR* sub_section,
00489                                                int create,
00490                                                ACE_Configuration_Section_Key& result)
00491 {
00492   if (validate_name (sub_section, 1))
00493     return -1;
00494 
00495   HKEY base_key;
00496   if (load_key (base, base_key))
00497     return -1;
00498 
00499   int errnum;
00500   HKEY result_key;
00501   if ((errnum = ACE_TEXT_RegOpenKeyEx (base_key,
00502                                        sub_section,
00503                                        0,
00504                                        KEY_ALL_ACCESS,
00505                                        &result_key)) != ERROR_SUCCESS)
00506     {
00507       if (!create)
00508         {
00509           errno = errnum;
00510           return -1;
00511         }
00512 
00513       if ((errnum = ACE_TEXT_RegCreateKeyEx (base_key,
00514                                              sub_section,
00515                                              0,
00516                                              0,
00517                                              REG_OPTION_NON_VOLATILE,
00518                                              KEY_ALL_ACCESS,
00519                                              0,
00520                                              &result_key,
00521 #if defined (__MINGW32__)
00522                                              (PDWORD) 0
00523 #else
00524                                              0
00525 #endif /* __MINGW32__ */
00526                                              )) != ERROR_SUCCESS)
00527         {
00528           errno = errnum;
00529           return -1;
00530         }
00531     }
00532 
00533   ACE_Section_Key_Win32 *temp;
00534 
00535   ACE_NEW_RETURN (temp, ACE_Section_Key_Win32 (result_key), -1);
00536   result = ACE_Configuration_Section_Key (temp);
00537   return 0;
00538 }
00539 
00540 int
00541 ACE_Configuration_Win32Registry::remove_section (const ACE_Configuration_Section_Key& key,
00542                                                  const ACE_TCHAR* sub_section,
00543                                                  int recursive)
00544 {
00545   if (validate_name (sub_section))
00546     return -1;
00547 
00548   HKEY base_key;
00549   if (load_key (key, base_key))
00550     return -1;
00551 
00552   if (recursive)
00553     {
00554       ACE_Configuration_Section_Key section;
00555       if (open_section (key, sub_section, 0, section))
00556         return -1;
00557 
00558       HKEY sub_key;
00559       if (load_key (section, sub_key))
00560         return -1;
00561 
00562       ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
00563       DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
00564       // Note we don't increment the index because the
00565       // enumeration becomes invalid if we change the
00566       // subkey, which we do when we delete it.  By leaving
00567       // it 0, we always delete the top entry
00568       while (ACE_TEXT_RegEnumKeyEx (sub_key,
00569                                     0,
00570                                     name_buffer,
00571                                     &buffer_size,
00572                                     0,
00573                                     0,
00574                                     0,
00575                                     0) == ERROR_SUCCESS)
00576         {
00577           remove_section (section, name_buffer, 1);
00578           buffer_size = ACE_DEFAULT_BUFSIZE;
00579         }
00580     }
00581 
00582   int errnum;
00583   errnum = ACE_TEXT_RegDeleteKey (base_key, sub_section);
00584   if (errnum != ERROR_SUCCESS)
00585     {
00586       errno = errnum;
00587       return -1;
00588     }
00589 
00590   return 0;
00591 }
00592 
00593 int
00594 ACE_Configuration_Win32Registry::enumerate_values (const ACE_Configuration_Section_Key& key,
00595                                                    int index,
00596                                                    ACE_TString& name,
00597                                                    VALUETYPE& type)
00598 {
00599   HKEY base_key;
00600   if (load_key (key, base_key))
00601     return -1;
00602 
00603   ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
00604   DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
00605   DWORD value_type;
00606 
00607   int rc = ACE_TEXT_RegEnumValue (base_key,
00608                                   index,
00609                                   name_buffer,
00610                                   &buffer_size,
00611                                   0,
00612                                   &value_type,
00613                                   0,
00614                                   0);
00615   if (rc == ERROR_NO_MORE_ITEMS)
00616     return 1;
00617   else if (rc != ERROR_SUCCESS)
00618     {
00619       errno = rc;
00620       return -1;
00621     }
00622 
00623   name = name_buffer;
00624 
00625   switch (value_type)
00626     {
00627     case REG_BINARY:
00628       type = BINARY;
00629       break;
00630     case REG_SZ:
00631       type = STRING;
00632       break;
00633     case REG_DWORD:
00634       type = INTEGER;
00635       break;
00636     default:
00637       type = INVALID;
00638     }
00639 
00640   return 0;
00641 }
00642 
00643 int
00644 ACE_Configuration_Win32Registry::enumerate_sections (const ACE_Configuration_Section_Key& key,
00645                                                      int index,
00646                                                      ACE_TString& name)
00647 {
00648   HKEY base_key;
00649   if (load_key (key, base_key))
00650     return -1;
00651 
00652   ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
00653   DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
00654   int rc = ACE_TEXT_RegEnumKeyEx (base_key,
00655                                   index,
00656                                   name_buffer,
00657                                   &buffer_size,
00658                                   0,
00659                                   0,
00660                                   0,
00661                                   0);
00662   if (rc == ERROR_NO_MORE_ITEMS)
00663     return 1;
00664   else if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS)
00665     {
00666       errno = rc;
00667       return -1;
00668     }
00669 
00670   name = name_buffer;
00671 
00672   return 0;
00673 }
00674 
00675 int
00676 ACE_Configuration_Win32Registry::set_string_value (const ACE_Configuration_Section_Key& key,
00677                                                    const ACE_TCHAR* name,
00678                                                    const ACE_TString& value)
00679 {
00680   const ACE_TCHAR *t_name = temp_name (name);
00681   if (validate_value_name (t_name))
00682     return -1;
00683 
00684   HKEY base_key;
00685   if (load_key (key, base_key))
00686     return -1;
00687 
00688   int errnum;
00689   DWORD len = static_cast<DWORD> (value.length () + 1);
00690   len *= sizeof (ACE_TCHAR);
00691   if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
00692                                        t_name,
00693                                        0,
00694                                        REG_SZ,
00695                                        (BYTE *) value.fast_rep (),
00696                                         len))
00697       != ERROR_SUCCESS)
00698     {
00699       errno = errnum;
00700       return -1;
00701     }
00702 
00703   return 0;
00704 }
00705 
00706 int
00707 ACE_Configuration_Win32Registry::set_integer_value (const ACE_Configuration_Section_Key& key,
00708                                                     const ACE_TCHAR* name,
00709                                                     u_int value)
00710 {
00711   const ACE_TCHAR *t_name = temp_name (name);
00712   if (validate_value_name (t_name))
00713     return -1;
00714 
00715   HKEY base_key;
00716   if (load_key (key, base_key))
00717     return -1;
00718 
00719   int errnum;
00720   if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
00721                                         t_name,
00722                                         0,
00723                                         REG_DWORD,
00724                                         (BYTE *) &value,
00725                                         sizeof (value))) != ERROR_SUCCESS)
00726     {
00727       errno = errnum;
00728       return -1;
00729     }
00730 
00731   return 0;
00732 }
00733 
00734 int
00735 ACE_Configuration_Win32Registry::set_binary_value (const ACE_Configuration_Section_Key& key,
00736                                                    const ACE_TCHAR* name,
00737                                                    const void* data,
00738                                                    size_t length)
00739 {
00740   const ACE_TCHAR *t_name = temp_name (name);
00741   if (validate_value_name (t_name))
00742     return -1;
00743 
00744   HKEY base_key;
00745   if (load_key (key, base_key))
00746     return -1;
00747 
00748   int errnum;
00749   if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
00750                                         t_name,
00751                                         0,
00752                                         REG_BINARY,
00753                                         (BYTE *) data,
00754                                         static_cast<DWORD> (length)))
00755       != ERROR_SUCCESS)
00756     {
00757       errno = errnum;
00758       return -1;
00759     }
00760 
00761   return 0;
00762 }
00763 
00764 int
00765 ACE_Configuration_Win32Registry::get_string_value (const ACE_Configuration_Section_Key& key,
00766                                                    const ACE_TCHAR* name,
00767                                                    ACE_TString& value)
00768 {
00769   const ACE_TCHAR *t_name = temp_name (name);
00770   if (validate_value_name (t_name))
00771     return -1;
00772 
00773   HKEY base_key;
00774   if (load_key (key, base_key))
00775     return -1;
00776 
00777   // Get the size of the binary data from windows
00778   int errnum;
00779   DWORD buffer_length = 0;
00780   DWORD type;
00781   if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
00782                                           t_name,
00783                                           0,
00784                                           &type,
00785                                           (BYTE *) 0,
00786                                           &buffer_length)) != ERROR_SUCCESS)
00787     {
00788       errno = errnum;
00789       return -1;
00790     }
00791 
00792   if (type != REG_SZ)
00793     {
00794       errno = ERROR_INVALID_DATATYPE;
00795       return -1;
00796     }
00797 
00798   ACE_TCHAR *temp = 0;
00799   ACE_NEW_RETURN (temp,
00800                   ACE_TCHAR[buffer_length],
00801                   -1);
00802 
00803   ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer (temp);
00804 
00805   if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
00806                                           t_name,
00807                                           0,
00808                                           &type,
00809                                           (BYTE *) buffer.get (),
00810                                           &buffer_length)) != ERROR_SUCCESS)
00811     {
00812       errno = errnum;
00813       return -1;
00814     }
00815 
00816   value = buffer.get ();
00817   return 0;
00818 }
00819 
00820 int
00821 ACE_Configuration_Win32Registry::get_integer_value (const ACE_Configuration_Section_Key& key,
00822                                                     const ACE_TCHAR* name,
00823                                                     u_int& value)
00824 {
00825   const ACE_TCHAR *t_name = temp_name (name);
00826   if (validate_value_name (t_name))
00827     return -1;
00828 
00829   HKEY base_key;
00830   if (load_key (key, base_key))
00831     return -1;
00832 
00833   int errnum;
00834   DWORD length = sizeof (value);
00835   DWORD type;
00836   if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
00837                                           t_name,
00838                                           0,
00839                                           &type,
00840                                           (BYTE *) &value,
00841                                           &length)) != ERROR_SUCCESS)
00842     {
00843       errno = errnum;
00844       return -1;
00845     }
00846 
00847   if (type != REG_DWORD)
00848     {
00849       errno = ERROR_INVALID_DATATYPE;
00850       return -1;
00851     }
00852 
00853   return 0;
00854 }
00855 
00856 int
00857 ACE_Configuration_Win32Registry::get_binary_value (
00858   const ACE_Configuration_Section_Key &key,
00859   const ACE_TCHAR *name,
00860   void *&data,
00861   size_t &length)
00862 {
00863   const ACE_TCHAR *t_name = temp_name (name);
00864   if (validate_value_name (t_name))
00865     return -1;
00866 
00867   HKEY base_key;
00868   if (load_key (key, base_key))
00869     return -1;
00870 
00871   // Get the size of the binary data from windows
00872   int errnum;
00873   DWORD buffer_length = 0;
00874   DWORD type;
00875   if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
00876                                           t_name,
00877                                           0,
00878                                           &type,
00879                                           (BYTE *) 0,
00880                                           &buffer_length)) != ERROR_SUCCESS)
00881     {
00882       errno = errnum;
00883       return -1;
00884     }
00885 
00886   if (type != REG_BINARY)
00887     {
00888       errno = ERROR_INVALID_DATATYPE;
00889       return -1;
00890     }
00891 
00892   length = buffer_length;
00893 
00894   BYTE * the_data = 0;
00895   ACE_NEW_RETURN (the_data, BYTE[length], -1);
00896   ACE_Auto_Basic_Array_Ptr<BYTE> safe_data (the_data);
00897 
00898   if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
00899                                           t_name,
00900                                           0,
00901                                           &type,
00902                                           the_data,
00903                                           &buffer_length)) != ERROR_SUCCESS)
00904     {
00905       data = 0;
00906       errno = errnum;
00907       return -1;
00908     }
00909 
00910   data = safe_data.release ();
00911 
00912   return 0;
00913 }
00914 
00915 int
00916 ACE_Configuration_Win32Registry::find_value (const ACE_Configuration_Section_Key& key,
00917                                              const ACE_TCHAR* name,
00918                                              VALUETYPE& type_out)
00919 {
00920   const ACE_TCHAR *t_name = temp_name (name);
00921   if (validate_value_name (t_name))
00922     return -1;
00923 
00924   HKEY base_key;
00925   if (load_key (key, base_key))
00926     return -1;
00927 
00928   DWORD buffer_length=0;
00929   DWORD type;
00930   int result=ACE_TEXT_RegQueryValueEx (base_key,
00931                                        t_name,
00932                                        0,
00933                                        &type,
00934                                        0,
00935                                        &buffer_length);
00936   if (result != ERROR_SUCCESS)
00937     {
00938       errno = result;
00939       return -1;
00940     }
00941 
00942   switch (type)
00943     {
00944     case REG_SZ:
00945       type_out = STRING;
00946       break;
00947     case REG_DWORD:
00948       type_out = INTEGER;
00949       break;
00950     case REG_BINARY:
00951       type_out = BINARY;
00952       break;
00953     default:
00954       return -1; // unknown type
00955     }
00956 
00957   return 0;
00958 }
00959 
00960 int
00961 ACE_Configuration_Win32Registry::remove_value (const ACE_Configuration_Section_Key& key,
00962                                                const ACE_TCHAR* name)
00963 {
00964   const ACE_TCHAR *t_name = temp_name (name);
00965   if (validate_value_name (t_name))
00966     return -1;
00967 
00968   HKEY base_key;
00969   if (load_key (key, base_key))
00970     return -1;
00971 
00972   int errnum;
00973   if ((errnum = ACE_TEXT_RegDeleteValue (base_key, t_name)) != ERROR_SUCCESS)
00974     {
00975       errno = errnum;
00976       return -1;
00977     }
00978 
00979   return 0;
00980 }
00981 
00982 
00983 int
00984 ACE_Configuration_Win32Registry::load_key (const ACE_Configuration_Section_Key& key,
00985                                            HKEY& hKey)
00986 {
00987   ACE_Section_Key_Win32* pKey = dynamic_cast<ACE_Section_Key_Win32*> (get_internal_key (key));
00988   if (!pKey)
00989     return -1;
00990 
00991   hKey = pKey->hKey_;
00992   return 0;
00993 }
00994 
00995 HKEY
00996 ACE_Configuration_Win32Registry::resolve_key (HKEY hKey,
00997                                               const ACE_TCHAR* path,
00998                                               int create)
00999 {
01000   HKEY result = 0;
01001   // Make a copy of hKey
01002   int errnum;
01003 #if defined (ACE_HAS_WINCE)
01004   if ((errnum = RegOpenKeyEx (hKey, 0, 0, 0, &result)) != ERROR_SUCCESS)
01005 #else
01006   if ((errnum = RegOpenKey (hKey, 0, &result)) != ERROR_SUCCESS)
01007 #endif  // ACE_HAS_WINCE
01008     {
01009       errno = errnum;
01010       return 0;
01011     }
01012 
01013   // recurse through the path
01014   ACE_TCHAR *temp_path = 0;
01015   ACE_NEW_RETURN (temp_path,
01016                   ACE_TCHAR[ACE_OS::strlen (path) + 1],
01017                   0);
01018   ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> pData (temp_path);
01019   ACE_OS::strcpy (pData.get (), path);
01020   ACE_Tokenizer parser (pData.get ());
01021   parser.delimiter_replace ('\\', '\0');
01022   parser.delimiter_replace ('/', '\0');
01023 
01024   for (ACE_TCHAR *temp = parser.next ();
01025        temp != 0;
01026        temp = parser.next ())
01027     {
01028       // Open the key
01029       HKEY subkey;
01030 
01031 #if defined (ACE_HAS_WINCE)
01032       if ((errnum = ACE_TEXT_RegOpenKeyEx (result,
01033                                            temp,
01034                                            0,
01035                                            0,
01036                                            &subkey)) != ERROR_SUCCESS)
01037 #else
01038       if ((errnum = ACE_TEXT_RegOpenKey (result,
01039                                          temp,
01040                                          &subkey)) != ERROR_SUCCESS)
01041 #endif  // ACE_HAS_WINCE
01042         {
01043           // try creating it
01044           if (!create || (errnum = ACE_TEXT_RegCreateKeyEx (result,
01045                                                             temp,
01046                                                             0,
01047                                                             0,
01048                                                             0,
01049                                                             KEY_ALL_ACCESS,
01050                                                             0,
01051                                                             &subkey,
01052 #if defined (__MINGW32__)
01053                                                             (PDWORD) 0
01054 #else
01055                                                             0
01056 #endif /* __MINGW32__ */
01057                                                             )) !=ERROR_SUCCESS)
01058             {
01059               errno = errnum;
01060               // error
01061               ::RegCloseKey (result);
01062               return 0;
01063             }
01064         }
01065       // release our open key handle
01066       ::RegCloseKey (result);
01067       result = subkey;
01068     }
01069 
01070   return result;
01071 }
01072 
01073 #endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */
01074 
01075 ///////////////////////////////////////////////////////////////
01076 
01077 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void)
01078   : type_ (ACE_Configuration::INVALID),
01079     length_ (0)
01080 {
01081   this->data_.ptr_ = 0;
01082 }
01083 
01084 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (ACE_TCHAR* string)
01085   : type_ (ACE_Configuration::STRING),
01086     length_ (0)
01087 {
01088   this->data_.ptr_ = string;
01089 }
01090 
01091 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (u_int integer)
01092   : type_ (ACE_Configuration::INTEGER),
01093     length_ (0)
01094 {
01095   this->data_.int_ = integer;
01096 }
01097 
01098 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void* data, size_t length)
01099   : type_ (ACE_Configuration::BINARY),
01100     length_ (length)
01101 {
01102   this->data_.ptr_ = data;
01103 }
01104 
01105 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (const ACE_Configuration_Value_IntId& rhs)
01106   : type_ (rhs.type_),
01107     data_ (rhs.data_),
01108     length_ (rhs.length_)
01109 {
01110 }
01111 
01112 ACE_Configuration_Value_IntId::~ACE_Configuration_Value_IntId (void)
01113 {
01114 }
01115 
01116 ACE_Configuration_Value_IntId& ACE_Configuration_Value_IntId::operator= (const ACE_Configuration_Value_IntId& rhs)
01117 {
01118   if (this != &rhs)
01119     {
01120       type_ = rhs.type_;
01121       data_ = rhs.data_;
01122       length_ = rhs.length_;
01123     }
01124   return *this;
01125 }
01126 
01127 void
01128 ACE_Configuration_Value_IntId::free (ACE_Allocator *alloc)
01129 {
01130   if (this->type_ == ACE_Configuration::STRING
01131       || this->type_ == ACE_Configuration::BINARY)
01132     alloc->free (data_.ptr_);
01133   // Do nothing in other cases...
01134 }
01135 
01136 ACE_Configuration_ExtId::ACE_Configuration_ExtId (void)
01137   : name_ (0)
01138 {
01139 }
01140 
01141 ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_TCHAR* name)
01142   : name_ (name)
01143 {
01144 }
01145 
01146 ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_Configuration_ExtId& rhs)
01147   : name_ (rhs.name_)
01148 {
01149 }
01150 
01151 ACE_Configuration_ExtId::~ACE_Configuration_ExtId (void)
01152 {
01153 }
01154 
01155 ACE_Configuration_ExtId& ACE_Configuration_ExtId::operator= (const ACE_Configuration_ExtId& rhs)
01156 {
01157   if (this != &rhs)
01158     name_ = rhs.name_;
01159 
01160   return *this;
01161 }
01162 
01163 bool
01164 ACE_Configuration_ExtId::operator== (const ACE_Configuration_ExtId& rhs) const
01165 {
01166   return (ACE_OS::strcasecmp (name_, rhs.name_) == 0);
01167 }
01168 
01169 bool
01170 ACE_Configuration_ExtId::operator!= (const ACE_Configuration_ExtId& rhs) const
01171 {
01172   return !this->operator== (rhs);
01173 }
01174 
01175 u_long
01176 ACE_Configuration_ExtId::hash (void) const
01177 {
01178   ACE_TString temp (name_, 0, false);
01179   return temp.hash ();
01180 }
01181 
01182 void
01183 ACE_Configuration_ExtId::free (ACE_Allocator *alloc)
01184 {
01185   alloc->free ((void *) (name_));
01186 }
01187 
01188 ///////////////////////////////////////////////////////////////////////
01189 
01190 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (void)
01191   : value_hash_map_ (0),
01192     section_hash_map_ (0)
01193 {
01194 }
01195 
01196 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (VALUE_MAP* value_hash_map, SUBSECTION_MAP* section_hash_map)
01197   : value_hash_map_ (value_hash_map),
01198     section_hash_map_ (section_hash_map)
01199 {
01200 }
01201 
01202 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (const ACE_Configuration_Section_IntId& rhs)
01203   : value_hash_map_ (rhs.value_hash_map_),
01204     section_hash_map_ (rhs.section_hash_map_)
01205 {
01206 
01207 }
01208 
01209 ACE_Configuration_Section_IntId::~ACE_Configuration_Section_IntId ()
01210 {
01211 }
01212 
01213 ACE_Configuration_Section_IntId&
01214 ACE_Configuration_Section_IntId::operator= (const ACE_Configuration_Section_IntId& rhs)
01215 {
01216   if (this != &rhs)
01217     {
01218       value_hash_map_ = rhs.value_hash_map_;
01219       section_hash_map_ = rhs.section_hash_map_;
01220     }
01221   return *this;
01222 }
01223 
01224 void
01225 ACE_Configuration_Section_IntId::free (ACE_Allocator *alloc)
01226 {
01227   alloc->free ((void *) (value_hash_map_));
01228   alloc->free ((void *) (section_hash_map_));
01229 }
01230 
01231 ACE_Configuration_Section_Key_Heap::ACE_Configuration_Section_Key_Heap (const ACE_TCHAR* path)
01232   : path_ (0),
01233     value_iter_ (0),
01234     section_iter_ (0)
01235 {
01236   path_ = ACE_OS::strdup (path);
01237 }
01238 
01239 ACE_Configuration_Section_Key_Heap::~ACE_Configuration_Section_Key_Heap ()
01240 {
01241   delete value_iter_;
01242   delete section_iter_;
01243   ACE_OS::free (path_);
01244 }
01245 
01246 //////////////////////////////////////////////////////////////////////////////
01247 
01248 ACE_Configuration_Heap::ACE_Configuration_Heap (void)
01249   : allocator_ (0),
01250     index_ (0),
01251     default_map_size_ (0)
01252 {
01253   ACE_Configuration_Section_Key_Heap *temp = 0;
01254 
01255   ACE_NEW (temp, ACE_Configuration_Section_Key_Heap (ACE_TEXT ("")));
01256   root_ = ACE_Configuration_Section_Key (temp);
01257 }
01258 
01259 ACE_Configuration_Heap::~ACE_Configuration_Heap (void)
01260 {
01261   if (allocator_)
01262     allocator_->sync ();
01263 
01264   delete allocator_;
01265 }
01266 
01267 int
01268 ACE_Configuration_Heap::open (size_t default_map_size)
01269 {
01270   default_map_size_ = default_map_size;
01271   // Create the allocator with the appropriate options.
01272   // The name used for  the lock is the same as one used
01273   // for the file.
01274   ACE_NEW_RETURN (this->allocator_,
01275                   HEAP_ALLOCATOR (),
01276                   -1);
01277   return create_index ();
01278 }
01279 
01280 
01281 int
01282 ACE_Configuration_Heap::open (const ACE_TCHAR* file_name,
01283                               void* base_address,
01284                               size_t default_map_size)
01285 {
01286   default_map_size_ = default_map_size;
01287 
01288   // Make sure that the file name is of the legal length.
01289   if (ACE_OS::strlen (file_name) >= MAXNAMELEN + MAXPATHLEN)
01290     {
01291       errno = ENAMETOOLONG;
01292       return -1;
01293     }
01294 
01295   ACE_MMAP_Memory_Pool::OPTIONS options (base_address);
01296 
01297   // Create the allocator with the appropriate options.  The name used
01298   // for  the lock is the same as one used for the file.
01299   ACE_NEW_RETURN (this->allocator_,
01300                   PERSISTENT_ALLOCATOR (file_name,
01301                                         file_name,
01302                                         &options),
01303                   -1);
01304 
01305 #if !defined (ACE_LACKS_ACCESS)
01306   // Now check if the backing store has been created successfully.
01307   if (ACE_OS::access (file_name, F_OK) != 0)
01308     ACE_ERROR_RETURN ((LM_ERROR,
01309                        ACE_TEXT ("create_index\n")),
01310                       -1);
01311 #endif /* ACE_LACKS_ACCESS */
01312 
01313   return create_index ();
01314 }
01315 
01316 int
01317 ACE_Configuration_Heap::create_index (void)
01318 {
01319   void *section_index = 0;
01320 
01321   // This is the easy case since if we find hash table in the
01322   // memory-mapped file we know it's already initialized.
01323   if (this->allocator_->find (ACE_CONFIG_SECTION_INDEX, section_index) == 0)
01324     this->index_ = (SECTION_MAP *) section_index;
01325 
01326   // Create a new <index_> (because we've just created a new
01327   // memory-mapped file).
01328   else
01329     {
01330       size_t index_size = sizeof (SECTION_MAP);
01331       section_index = this->allocator_->malloc (index_size);
01332 
01333       if (section_index == 0
01334           || create_index_helper (section_index) == -1
01335           || this->allocator_->bind (ACE_CONFIG_SECTION_INDEX,
01336                                      section_index) == -1)
01337         {
01338           // Attempt to clean up.
01339           ACE_ERROR ((LM_ERROR,
01340                       ACE_TEXT ("create_index failed\n")));
01341           this->allocator_->remove ();
01342           return -1;
01343         }
01344       // Add the root section
01345       return new_section (ACE_TEXT (""), root_);
01346     }
01347   return 0;
01348 }
01349 
01350 int
01351 ACE_Configuration_Heap::create_index_helper (void *buffer)
01352 {
01353   ACE_ASSERT (this->allocator_);
01354   this->index_ = new (buffer) SECTION_MAP (this->allocator_);
01355   return 0;
01356 }
01357 
01358 int
01359 ACE_Configuration_Heap::load_key (const ACE_Configuration_Section_Key& key,
01360                                   ACE_TString& name)
01361 {
01362   ACE_ASSERT (this->allocator_);
01363   ACE_Configuration_Section_Key_Heap* pKey =
01364     dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
01365 
01366   if (!pKey)
01367     {
01368       return -1;
01369     }
01370 
01371   ACE_TString temp (pKey->path_, 0, false);
01372   name.assign_nocopy (temp);
01373   return 0;
01374 }
01375 
01376 
01377 int
01378 ACE_Configuration_Heap::add_section (const ACE_Configuration_Section_Key& base,
01379                                      const ACE_TCHAR* sub_section,
01380                                      ACE_Configuration_Section_Key& result)
01381 {
01382   ACE_ASSERT (this->allocator_);
01383   ACE_TString section;
01384   if (load_key (base, section))
01385     return -1;
01386 
01387   // Find the base section
01388   ACE_Configuration_ExtId ExtId (section.fast_rep ());
01389   ACE_Configuration_Section_IntId IntId;
01390   if (index_->find (ExtId, IntId, allocator_))
01391     return -1;
01392 
01393   // See if this section already exists
01394   ACE_Configuration_ExtId SubSectionExtId (sub_section);
01395   int ignored = 0;
01396 
01397   if (!IntId.section_hash_map_->find (SubSectionExtId, ignored, allocator_))
01398     {
01399       // already exists!
01400       errno = EEXIST;
01401       return -1;
01402     }
01403 
01404   // Create the new section name
01405   // only prepend a separater if were not at the root
01406   if (section.length ())
01407     section += ACE_TEXT ("\\");
01408 
01409   section += sub_section;
01410 
01411   // Add it to the base section
01412   ACE_TCHAR* pers_name = (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (sub_section) + 1) * sizeof (ACE_TCHAR));
01413   ACE_OS::strcpy (pers_name, sub_section);
01414   ACE_Configuration_ExtId SSExtId (pers_name);
01415   if (IntId.section_hash_map_->bind (SSExtId, ignored, allocator_))
01416     {
01417       allocator_->free (pers_name);
01418       return -1;
01419     }
01420   return (new_section (section, result));
01421 }
01422 
01423 int
01424 ACE_Configuration_Heap::new_section (const ACE_TString& section,
01425                                      ACE_Configuration_Section_Key& result)
01426 {
01427   ACE_ASSERT (this->allocator_);
01428   // Create a new section and add it to the global list
01429 
01430   // Allocate memory for items to be stored in the table.
01431   size_t section_len = section.length () + 1;
01432   ACE_TCHAR *ptr = (ACE_TCHAR*) this->allocator_->malloc (section_len * sizeof (ACE_TCHAR));
01433 
01434   int return_value = -1;
01435 
01436   if (ptr == 0)
01437     return -1;
01438   else
01439     {
01440       // Populate memory with data.
01441       ACE_OS::strcpy (ptr, section.fast_rep ());
01442 
01443       void *value_hash_map = 0;
01444       size_t map_size = sizeof (VALUE_MAP);
01445       value_hash_map = this->allocator_->malloc (map_size);
01446 
01447       // If allocation failed ...
01448       if (value_hash_map == 0)
01449         return -1;
01450 
01451       // Initialize allocated hash map through placement new.
01452       if (value_open_helper (default_map_size_, value_hash_map ) == -1)
01453         {
01454           this->allocator_->free (value_hash_map );
01455           return -1;
01456         }
01457 
01458       // create the section map
01459       void* section_hash_map = 0;
01460       map_size = sizeof (SUBSECTION_MAP);
01461       section_hash_map = this->allocator_->malloc (map_size);
01462 
01463       // If allocation failed
01464       if (section_hash_map == 0)
01465         return -1;
01466 
01467       // initialize allocated hash map through placement new
01468       if (section_open_helper (default_map_size_, section_hash_map) == -1)
01469         {
01470           this->allocator_->free (value_hash_map );
01471           this->allocator_->free (section_hash_map);
01472           return -1;
01473         }
01474 
01475       ACE_Configuration_ExtId name (ptr);
01476       ACE_Configuration_Section_IntId entry ((VALUE_MAP*) value_hash_map,
01477                                              (SUBSECTION_MAP*) section_hash_map);
01478 
01479       // Do a normal bind.  This will fail if there's already an
01480       // entry with the same name.
01481       return_value = this->index_->bind (name, entry, this->allocator_);
01482 
01483       if (return_value == 1      /* Entry already existed so bind failed. */
01484           || return_value == -1  /* Unable to bind for other reasons. */)
01485         {
01486           // Free our dynamically allocated memory.
01487           this->allocator_->free (static_cast<void *> (ptr));
01488           return return_value;
01489         }
01490 
01491       // If bind () succeed, it will automatically sync
01492       // up the map manager entry.  However, we must sync up our
01493       // name/value memory.
01494       this->allocator_->sync (ptr, section_len);
01495     }
01496 
01497   // set the result
01498   ACE_Configuration_Section_Key_Heap *temp;
01499   ACE_NEW_RETURN (temp,
01500                   ACE_Configuration_Section_Key_Heap (ptr),
01501                   -1);
01502   result = ACE_Configuration_Section_Key (temp);
01503   return return_value;
01504 }
01505 
01506 int
01507 ACE_Configuration_Heap::value_open_helper (size_t hash_table_size,
01508                                           void *buffer)
01509 {
01510   ACE_ASSERT (this->allocator_);
01511   new (buffer) VALUE_MAP (hash_table_size, this->allocator_);
01512   return 0;
01513 }
01514 
01515 int
01516 ACE_Configuration_Heap::section_open_helper (size_t hash_table_size,
01517                                              void *buffer)
01518 {
01519   ACE_ASSERT (this->allocator_);
01520   new (buffer) SUBSECTION_MAP (hash_table_size, this->allocator_);
01521   return 0;
01522 }
01523 
01524 int
01525 ACE_Configuration_Heap::open_section (const ACE_Configuration_Section_Key& base,
01526                                       const ACE_TCHAR* sub_section,
01527                                       int create,
01528                                       ACE_Configuration_Section_Key& result)
01529 {
01530   ACE_ASSERT (this->allocator_);
01531   if (validate_name (sub_section, 1))    // 1 == allow_path
01532     return -1;
01533 
01534   result = base;
01535 
01536   for (const ACE_TCHAR* separator;
01537        (separator = ACE_OS::strchr (sub_section, ACE_TEXT ('\\'))) != 0;
01538        )
01539     {
01540       ACE_TString simple_section (sub_section, separator - sub_section);
01541       int ret_val =
01542         open_simple_section (result, simple_section.c_str (), create, result);
01543       if (ret_val)
01544         return ret_val;
01545       sub_section = separator + 1;
01546     }
01547 
01548   return open_simple_section (result, sub_section, create, result);
01549 }
01550 
01551 int
01552 ACE_Configuration_Heap::open_simple_section (const ACE_Configuration_Section_Key& base,
01553                                              const ACE_TCHAR* sub_section,
01554                                              int create,
01555                                              ACE_Configuration_Section_Key& result)
01556 {
01557   ACE_TString section (0, 0, false);
01558 
01559   if (load_key (base, section))
01560     {
01561       return -1;
01562     }
01563 
01564   // Only add the \\ if were not at the root
01565   if (section.length ())
01566     {
01567       section += ACE_TEXT ("\\");
01568     }
01569 
01570   section += sub_section;
01571 
01572   // resolve the section
01573   ACE_Configuration_ExtId ExtId (section.fast_rep ());
01574   ACE_Configuration_Section_IntId IntId;
01575 
01576   if (index_->find (ExtId, IntId, allocator_))
01577     {
01578       if (!create)
01579         {
01580           errno = ENOENT;
01581           return -1;
01582         }
01583 
01584       return add_section (base, sub_section, result);
01585     }
01586 
01587   ACE_Configuration_Section_Key_Heap *temp;
01588   ACE_NEW_RETURN (temp,
01589                   ACE_Configuration_Section_Key_Heap (section.fast_rep ()),
01590                   -1);
01591   result = ACE_Configuration_Section_Key (temp);
01592   return 0;
01593 }
01594 
01595 int
01596 ACE_Configuration_Heap::remove_section (const ACE_Configuration_Section_Key& key,
01597                                         const ACE_TCHAR* sub_section,
01598                                         int recursive)
01599 {
01600   ACE_ASSERT (this->allocator_);
01601   if (validate_name (sub_section))
01602     return -1;
01603 
01604   ACE_TString section;
01605   if (load_key (key, section))
01606     return -1;
01607 
01608   // Find this key
01609   ACE_Configuration_ExtId ParentExtId (section.fast_rep ());
01610   ACE_Configuration_Section_IntId ParentIntId;
01611   if (index_->find (ParentExtId, ParentIntId, allocator_))
01612     return -1;// no parent key
01613 
01614   // Find this subkey
01615   if (section.length ())
01616     section += ACE_TEXT ("\\");
01617 
01618   section += sub_section;
01619   ACE_Configuration_ExtId SectionExtId (section.fast_rep ());
01620   SECTION_HASH::ENTRY* section_entry;
01621   SECTION_HASH* hashmap = index_;
01622   if (hashmap->find (SectionExtId, section_entry))
01623     return -1;
01624 
01625   if (recursive)
01626     {
01627       ACE_Configuration_Section_Key section;
01628       if (open_section (key, sub_section, 0, section))
01629         return -1;
01630 
01631       int index = 0;
01632       ACE_TString name;
01633       while (!enumerate_sections (section, index, name))
01634         {
01635           if (remove_section (section, name.fast_rep (), 1))
01636             return -1;
01637 
01638           ++index;
01639         }
01640     }
01641 
01642   // Now make sure we dont have any subkeys
01643   if (section_entry->int_id_.section_hash_map_->current_size ())
01644     {
01645       errno = ENOTEMPTY;
01646       return -1;
01647     }
01648 
01649   // Now remove subkey from parent key
01650   ACE_Configuration_ExtId SubSExtId (sub_section);
01651   SUBSECTION_HASH::ENTRY* subsection_entry;
01652   if (((SUBSECTION_HASH*)ParentIntId.section_hash_map_)->
01653       find (SubSExtId, subsection_entry))
01654     return -1;
01655 
01656   if (ParentIntId.section_hash_map_->unbind (SubSExtId, allocator_))
01657     return -1;
01658 
01659   subsection_entry->ext_id_.free (allocator_);
01660 
01661   // Remember the pointers so we can free them after we unbind
01662   ACE_Configuration_ExtId ExtIdToFree (section_entry->ext_id_);
01663   ACE_Configuration_Section_IntId IntIdToFree (section_entry->int_id_);
01664 
01665   // iterate over all values and free memory
01666   VALUE_HASH* value_hash_map = section_entry->int_id_.value_hash_map_;
01667   VALUE_HASH::ITERATOR value_iter = value_hash_map->begin ();
01668   while (!value_iter.done ())
01669     {
01670       VALUE_HASH::ENTRY* value_entry = 0;
01671       if (!value_iter.next (value_entry))
01672         return 1;
01673 
01674       value_entry->ext_id_.free (allocator_);
01675       value_entry->int_id_.free (allocator_);
01676 
01677       value_iter.advance ();
01678     }
01679 
01680   // remove it
01681   if (index_->unbind (SectionExtId, allocator_))
01682     return -1;
01683 
01684   value_hash_map->close ();
01685   section_entry->int_id_.section_hash_map_->close (allocator_);
01686 
01687   // Free the memory
01688   ExtIdToFree.free (allocator_);
01689   IntIdToFree.free (allocator_);
01690 
01691   return 0;
01692 }
01693 
01694 int
01695 ACE_Configuration_Heap::enumerate_values (const ACE_Configuration_Section_Key& key,
01696                                           int index,
01697                                           ACE_TString& name,
01698                                           VALUETYPE& type)
01699 {
01700   ACE_ASSERT (this->allocator_);
01701   ACE_Configuration_Section_Key_Heap* pKey =
01702     dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
01703   if (!pKey)
01704     return -1;
01705 
01706   name = pKey->path_;
01707 
01708   // resolve the section
01709   ACE_Configuration_ExtId ExtId (pKey->path_);
01710   ACE_Configuration_Section_IntId IntId;
01711   if (index_->find (ExtId, IntId, allocator_))
01712     return -1;
01713 
01714   // Handle iterator resets
01715   if (index == 0)
01716     {
01717       ACE_Hash_Map_Manager_Ex<ACE_Configuration_ExtId ,
01718                               ACE_Configuration_Value_IntId,
01719                               ACE_Hash<ACE_Configuration_ExtId>,
01720                               ACE_Equal_To<ACE_Configuration_ExtId>,
01721                               ACE_Null_Mutex>* hash_map = IntId.value_hash_map_;
01722       delete pKey->value_iter_;
01723 
01724       ACE_NEW_RETURN (pKey->value_iter_,
01725                       VALUE_HASH::ITERATOR (hash_map->begin ()),
01726                       -1);
01727     }
01728 
01729   // Get the next entry
01730   ACE_Hash_Map_Entry<ACE_Configuration_ExtId, ACE_Configuration_Value_IntId>* entry = 0;
01731 
01732   if (!pKey->value_iter_->next (entry))
01733     return 1;
01734 
01735   // Return the value of the iterator and advance it
01736   name = entry->ext_id_.name_;
01737   type = entry->int_id_.type_;
01738   pKey->value_iter_->advance ();
01739 
01740   return 0;
01741 }
01742 
01743 int
01744 ACE_Configuration_Heap::enumerate_sections (const ACE_Configuration_Section_Key& key,
01745                                             int index,
01746                                             ACE_TString& name)
01747 {
01748   ACE_ASSERT (this->allocator_);
01749   // cast to a heap section key
01750   ACE_Configuration_Section_Key_Heap* pKey =
01751     dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
01752   if (!pKey)
01753     return -1;  // not a heap key!
01754 
01755   // resolve the section
01756   ACE_Configuration_ExtId ExtId (pKey->path_);
01757   ACE_Configuration_Section_IntId IntId;
01758   if (index_->find (ExtId, IntId, allocator_))
01759     return -1; // unknown section
01760 
01761   // Handle iterator resets
01762   if (index == 0)
01763     {
01764       if (pKey->section_iter_)
01765         delete pKey->section_iter_;
01766 
01767       ACE_NEW_RETURN (pKey->section_iter_,
01768                       SUBSECTION_HASH::ITERATOR (IntId.section_hash_map_->begin ()),
01769                       -1);
01770     }
01771 
01772   // Get the next entry
01773   ACE_Hash_Map_Entry<ACE_Configuration_ExtId, int>* entry = 0;
01774   if (!pKey->section_iter_->next (entry))
01775     return 1;
01776 
01777   // Return the value of the iterator and advance it
01778   pKey->section_iter_->advance ();
01779   name = entry->ext_id_.name_;
01780 
01781   return 0;
01782 }
01783 
01784 int
01785 ACE_Configuration_Heap::set_string_value (const ACE_Configuration_Section_Key& key,
01786                                           const ACE_TCHAR* name,
01787                                           const ACE_TString& value)
01788 {
01789   ACE_ASSERT (this->allocator_);
01790   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
01791   if (validate_value_name (t_name))
01792     return -1;
01793 
01794   ACE_TString section;
01795   if (load_key (key, section))
01796     return -1;
01797 
01798   ACE_Configuration_ExtId section_ext (section.fast_rep ());
01799   ACE_Configuration_Section_IntId section_int;
01800   if (index_->find (section_ext, section_int, allocator_))
01801     return -1;
01802 
01803   // Get the entry for this item (if it exists)
01804   VALUE_HASH::ENTRY* entry;
01805   ACE_Configuration_ExtId item_name (t_name);
01806   if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
01807     {
01808       // found item, replace it
01809       // Free the old value
01810       entry->int_id_.free (allocator_);
01811       // Allocate the new value in this heap
01812       ACE_TCHAR* pers_value =
01813  (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
01814       ACE_OS::strcpy (pers_value, value.fast_rep ());
01815       ACE_Configuration_Value_IntId new_value_int (pers_value);
01816       entry->int_id_ = new_value_int;
01817     }
01818   else
01819     {
01820       // it doesn't exist, bind it
01821       ACE_TCHAR* pers_name =
01822  (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
01823       ACE_OS::strcpy (pers_name, t_name);
01824       ACE_TCHAR* pers_value =
01825  (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
01826       ACE_OS::strcpy (pers_value, value.fast_rep ());
01827       ACE_Configuration_ExtId item_name (pers_name);
01828       ACE_Configuration_Value_IntId item_value (pers_value);
01829       if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
01830         {
01831           allocator_->free (pers_value);
01832           allocator_->free (pers_name);
01833           return -1;
01834         }
01835       return 0;
01836     }
01837 
01838   return 0;
01839 }
01840 
01841 int
01842 ACE_Configuration_Heap::set_integer_value (const ACE_Configuration_Section_Key& key,
01843                                            const ACE_TCHAR* name,
01844                                            u_int value)
01845 {
01846   ACE_ASSERT (this->allocator_);
01847   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
01848   if (validate_value_name (t_name))
01849     return -1;
01850 
01851   // Get the section name from the key
01852   ACE_TString section;
01853   if (load_key (key, section))
01854     return -1;
01855 
01856   // Find this section
01857   ACE_Configuration_ExtId section_ext (section.fast_rep ());
01858   ACE_Configuration_Section_IntId section_int;
01859   if (index_->find (section_ext, section_int, allocator_))
01860     return -1;  // section does not exist
01861 
01862   // Get the entry for this item (if it exists)
01863   VALUE_HASH::ENTRY* entry;
01864   ACE_Configuration_ExtId item_name (t_name);
01865   if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
01866     {
01867       // found item, replace it
01868       ACE_Configuration_Value_IntId new_value_int (value);
01869       entry->int_id_ = new_value_int;
01870     }
01871   else
01872     {
01873       // it doesn't exist, bind it
01874       ACE_TCHAR* pers_name =
01875  (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
01876       ACE_OS::strcpy (pers_name, t_name);
01877       ACE_Configuration_ExtId item_name (pers_name);
01878       ACE_Configuration_Value_IntId item_value (value);
01879       if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
01880         {
01881           allocator_->free (pers_name);
01882           return -1;
01883         }
01884       return 0;
01885     }
01886 
01887   return 0;
01888 }
01889 
01890 int
01891 ACE_Configuration_Heap::set_binary_value (const ACE_Configuration_Section_Key& key,
01892                                           const ACE_TCHAR* name,
01893                                           const void* data,
01894                                           size_t length)
01895 {
01896   ACE_ASSERT (this->allocator_);
01897   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
01898   if (validate_value_name (t_name))
01899     return -1;
01900 
01901   // Get the section name from the key
01902   ACE_TString section;
01903   if (load_key (key, section))
01904     return -1;
01905 
01906   // Find this section
01907   ACE_Configuration_ExtId section_ext (section.fast_rep ());
01908   ACE_Configuration_Section_IntId section_int;
01909   if (index_->find (section_ext, section_int, allocator_))
01910     return -1;    // section does not exist
01911 
01912   // Get the entry for this item (if it exists)
01913   VALUE_HASH::ENTRY* entry;
01914   ACE_Configuration_ExtId item_name (t_name);
01915   if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
01916     {
01917       // found item, replace it
01918       // Free the old value
01919       entry->int_id_.free (allocator_);
01920       // Allocate the new value in this heap
01921       ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
01922       ACE_OS::memcpy (pers_value, data, length);
01923       ACE_Configuration_Value_IntId new_value_int (pers_value, length);
01924       entry->int_id_ = new_value_int;
01925     }
01926   else
01927     {
01928       // it doesn't exist, bind it
01929       ACE_TCHAR* pers_name =
01930  (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
01931       ACE_OS::strcpy (pers_name, t_name);
01932       ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
01933       ACE_OS::memcpy (pers_value, data, length);
01934       ACE_Configuration_ExtId item_name (pers_name);
01935       ACE_Configuration_Value_IntId item_value (pers_value, length);
01936       if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
01937         {
01938           allocator_->free (pers_value);
01939           allocator_->free (pers_name);
01940           return -1;
01941         }
01942       return 0;
01943     }
01944 
01945   return 0;
01946 }
01947 
01948 int
01949 ACE_Configuration_Heap::get_string_value (const ACE_Configuration_Section_Key& key,
01950                                           const ACE_TCHAR* name,
01951                                           ACE_TString& value)
01952 {
01953   ACE_ASSERT (this->allocator_);
01954   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
01955   if (validate_value_name (t_name))
01956     return -1;
01957 
01958   // Get the section name from the key
01959   ACE_TString section;
01960   if (load_key (key, section))
01961     return -1;
01962 
01963   // Find this section
01964   ACE_Configuration_ExtId ExtId (section.fast_rep ());
01965   ACE_Configuration_Section_IntId IntId;
01966   if (index_->find (ExtId, IntId, allocator_))
01967     return -1;    // section does not exist
01968 
01969   // See if it exists first
01970   ACE_Configuration_ExtId VExtId (t_name);
01971   ACE_Configuration_Value_IntId VIntId;
01972   if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
01973     return -1;    // unknown value
01974 
01975   // Check type
01976   if (VIntId.type_ != ACE_Configuration::STRING)
01977     {
01978       errno = ENOENT;
01979       return -1;
01980     }
01981 
01982   // everythings ok, return the data
01983   value = static_cast<ACE_TCHAR*> (VIntId.data_.ptr_);
01984   return 0;
01985 }
01986 
01987 int
01988 ACE_Configuration_Heap::get_integer_value (const ACE_Configuration_Section_Key& key,
01989                                            const ACE_TCHAR* name,
01990                                            u_int& value)
01991 {
01992   ACE_ASSERT (this->allocator_);
01993 
01994   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
01995   if (validate_value_name (t_name))
01996     return -1;
01997 
01998   // Get the section name from the key
01999   ACE_TString section (0, 0, false);
02000 
02001   if (this->load_key (key, section) != 0)
02002     {
02003       return -1;
02004     }
02005 
02006   // Find this section
02007   ACE_Configuration_ExtId ExtId (section.fast_rep ());
02008   ACE_Configuration_Section_IntId IntId;
02009 
02010   if (index_->find (ExtId, IntId, allocator_) != 0)
02011     {
02012       return -1;    // section does not exist
02013     }
02014 
02015 
02016   // See if it exists first
02017   ACE_Configuration_ExtId VExtId (t_name);
02018   ACE_Configuration_Value_IntId VIntId;
02019 
02020   if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_) != 0)
02021     {
02022       return -1;    // unknown value
02023     }
02024 
02025   // Check type
02026   if (VIntId.type_ != ACE_Configuration::INTEGER)
02027     {
02028       errno = ENOENT;
02029       return -1;
02030     }
02031 
02032   // Everythings ok, return the data
02033   value = VIntId.data_.int_;
02034   return 0;
02035 }
02036 
02037 int
02038 ACE_Configuration_Heap::get_binary_value (
02039   const ACE_Configuration_Section_Key& key,
02040   const ACE_TCHAR* name,
02041   void*& data,
02042   size_t& length)
02043 {
02044   ACE_ASSERT (this->allocator_);
02045   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
02046   if (validate_value_name (t_name))
02047     return -1;
02048 
02049   // Get the section name from the key
02050   ACE_TString section;
02051   if (load_key (key, section))
02052     return -1;
02053 
02054   // Find this section
02055   ACE_Configuration_ExtId ExtId (section.fast_rep ());
02056   ACE_Configuration_Section_IntId IntId;
02057   if (index_->find (ExtId, IntId, allocator_))
02058     return -1;    // section does not exist
02059 
02060   ACE_Configuration_ExtId VExtId (t_name);
02061   ACE_Configuration_Value_IntId VIntId;
02062   // See if it exists first
02063   if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
02064     return -1;    // unknown value
02065 
02066   // Check type
02067   if (VIntId.type_ != ACE_Configuration::BINARY)
02068     {
02069       errno = ENOENT;
02070       return -1;
02071     }
02072 
02073   // Make a copy
02074   ACE_NEW_RETURN (data, char[VIntId.length_], -1);
02075   ACE_OS::memcpy (data, VIntId.data_.ptr_, VIntId.length_);
02076   length = VIntId.length_;
02077   return 0;
02078 }
02079 
02080 int
02081 ACE_Configuration_Heap::find_value (const ACE_Configuration_Section_Key& key,
02082                                     const ACE_TCHAR* name,
02083                                     VALUETYPE& type_out)
02084 {
02085   ACE_ASSERT (this->allocator_);
02086   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
02087   if (validate_value_name (t_name))
02088     return -1;
02089 
02090   // Get the section name from the key
02091   ACE_TString section;
02092   if (load_key (key, section))
02093     return -1;
02094 
02095   // Find this section
02096   ACE_Configuration_ExtId ExtId (section.fast_rep ());
02097   ACE_Configuration_Section_IntId IntId;
02098   if (index_->find (ExtId, IntId, allocator_))
02099     return -1;    // section does not exist
02100 
02101   // Find it
02102   ACE_Configuration_ExtId ValueExtId (t_name);
02103   VALUE_HASH::ENTRY* value_entry;
02104   if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
02105     return -1;  // value does not exist
02106 
02107   type_out = value_entry->int_id_.type_;
02108   return 0;
02109 }
02110 
02111 int
02112 ACE_Configuration_Heap::remove_value (const ACE_Configuration_Section_Key& key,
02113                                       const ACE_TCHAR* name)
02114 {
02115   ACE_ASSERT (this->allocator_);
02116   const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
02117   if (validate_value_name (t_name))
02118     return -1;
02119 
02120   // Get the section name from the key
02121   ACE_TString section;
02122   if (load_key (key, section))
02123     return -1;
02124 
02125   // Find this section
02126   ACE_Configuration_ExtId ExtId (section.fast_rep ());
02127   ACE_Configuration_Section_IntId IntId;
02128   if (index_->find (ExtId, IntId, allocator_))
02129     return -1;    // section does not exist
02130 
02131   // Find it
02132   ACE_Configuration_ExtId ValueExtId (t_name);
02133   VALUE_HASH::ENTRY* value_entry;
02134   if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
02135     return -1;
02136 
02137   // free it
02138   value_entry->ext_id_.free (allocator_);
02139   value_entry->int_id_.free (allocator_);
02140 
02141   // Unbind it
02142   if (IntId.value_hash_map_->unbind (ValueExtId, allocator_))
02143     return -1;
02144 
02145   return 0;
02146 }
02147 
02148 ACE_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7