Configuration.cpp

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

Generated on Sun Jan 27 12:05:23 2008 for ACE by doxygen 1.3.6