Configuration.cpp

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

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