// $Id$ #define ACE_BUILD_DLL #include "ace/Configuration.h" #if !defined (__ACE_INLINE__) #include "ace/Configuration.i" #endif /* __ACE_INLINE__ */ ACE_Section_Key_Internal::ACE_Section_Key_Internal (void) : ref_count_ (0) { } ACE_Section_Key_Internal::~ACE_Section_Key_Internal (void) { } int ACE_Section_Key_Internal::add_ref (void) { ++ref_count_; return 0; } int ACE_Section_Key_Internal::dec_ref (void) { if (!--ref_count_) delete this; return 0; } ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (void) : key_ (0) { } ACE_Configuration_Section_Key::~ACE_Configuration_Section_Key (void) { if (key_) key_->dec_ref (); } ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (ACE_Section_Key_Internal* key) : key_ (key) { if (key_) key_->add_ref (); } ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (const ACE_Configuration_Section_Key& rhs) : key_ (rhs.key_) { if (key_) key_->add_ref (); } ACE_Configuration_Section_Key& ACE_Configuration_Section_Key::operator= (const ACE_Configuration_Section_Key& rhs) { if (this != &rhs) { if (key_) key_->dec_ref (); key_ = rhs.key_; if (key_) key_->add_ref (); } return *this; } ////////////////////////////////////////////////////////////////////////////// ACE_Configuration::ACE_Configuration (void) : root_ () { } ACE_Configuration::~ACE_Configuration (void) { } ACE_Section_Key_Internal* ACE_Configuration::get_internal_key (const ACE_Configuration_Section_Key& key) { return key.key_; } int ACE_Configuration::expand_path (const ACE_Configuration_Section_Key& key, const ACE_TString& path_in, ACE_Configuration_Section_Key& key_out, int create) { const TCHAR* begin = path_in.rep (); const TCHAR* end = 0; // Make a copy of key ACE_Configuration_Section_Key current_section = key; // recurse through the path while (1) { // Detmine the begin/ending of the key name end = ACE_OS::strchr (begin, '\\'); size_t length = end ? (size_t)(end-begin) : ACE_OS::strlen (begin); // Make sure length is not 0 if (!length) return -1; ACE_TString section (begin, length); // Open the section ACE_Configuration_Section_Key child_section; if (open_section (current_section, section.rep (), create, child_section)) return -1; current_section = child_section; // If end is NULL, we are done, return the result if (!end) { key_out = current_section; break; } begin = end + 1; } return 0; } int ACE_Configuration::validate_name (const TCHAR* name) { const TCHAR* pos = name; // make sure it doesn't contain any invalid characters while (*pos) { if (ACE_OS::strchr (ACE_TEXT ("\\]["), *pos)) return -1; pos++; } // Make sure its not too long if (pos - name > 255) return -2; return 0; } int ACE_Configuration::export_section (const ACE_Configuration_Section_Key& section, const ACE_TString& path, FILE* out) { // don't export the root if (path.length ()) { // Write out the section header ACE_TString header = ACE_TEXT ("["); header += path; header += "]"; header +="\n"; if (ACE_OS::fputs (ACE_MULTIBYTE_STRING (header.rep ()), out) < 0) return -1; // Write out each value int index = 0; ACE_TString name; VALUETYPE type; ACE_TString line; TCHAR int_value[32]; ACE_TString string_value; while (!enumerate_values (section, index, name, type)) { line = name + ACE_TEXT ("="); switch (type) { case INTEGER: { u_int value; if (get_integer_value (section, name.rep (), value)) return -2; ACE_OS::sprintf (ACE_MULTIBYTE_STRING (int_value), "#%d", value); line += int_value; break; } case STRING: { if (get_string_value (section, name.rep (), string_value)) return -2; line += ACE_TEXT ("\""); line += string_value; break; } case BINARY: { // not supported yet - maybe use BASE64 codeing? break; } default: return -3; } line += ACE_TEXT ("\n"); if (ACE_OS::fputs (ACE_MULTIBYTE_STRING (line.rep ()), out) < 0) return -4; index++; } } // Export all sub sections int index = 0; ACE_TString name; ACE_Configuration_Section_Key sub_key; ACE_TString sub_section; while (!enumerate_sections (section, index, name)) { ACE_TString sub_section (path); if (path.length ()) sub_section += ACE_TEXT ("\\"); sub_section += name; if (open_section (section, name.rep (), 0, sub_key)) return -5; if (export_section (sub_key, sub_section.rep (), out)) return -6; index++; } return 0; } int ACE_Configuration::export_config (const TCHAR* filename) { FILE* out = ACE_OS::fopen (ACE_MULTIBYTE_STRING (filename), "w"); if (!out) return -1; int result = export_section (root_, "", out); ACE_OS::fclose (out); return result; } int ACE_Configuration::import_config (const TCHAR* filename) { FILE* in = ACE_OS::fopen (ACE_MULTIBYTE_STRING (filename), "r"); if (!in) return -1; // XXX - change this to a dynamic buffer TCHAR buffer[4096]; ACE_Configuration_Section_Key section; while (ACE_OS::fgets (buffer, 4096, in)) { // Check for a comment if (buffer[0] == ';' || buffer[0] == '#') continue; if (buffer[0] == '[') { // We have a new section here, strip out the section name int length = ACE_OS::strlen (buffer); buffer[length - 2] = 0; if (expand_path (root_, buffer + 1, section, 1)) return -3; continue; } // assume this is a value, read in the value name TCHAR* end = ACE_OS::strchr (buffer, '='); if (!end) // no =, not a value so just skip it continue; // null terminate the name *end = 0; end++; // determine the type if (*end == '\"') { // string type if (set_string_value (section, buffer, end + 1)) return -4; } else if (*end == '#') { // number type u_int value = atoi (ACE_MULTIBYTE_STRING (end + 1)); if (set_integer_value (section, buffer, value)) return -4; } else { // invalid type, ignore continue; } } if (ferror (in)) return -1; return 0; } const ACE_Configuration_Section_Key& ACE_Configuration::root_section (void) { return root_; } ////////////////////////////////////////////////////////////////////////////// #if defined (WIN32) static const int ACE_DEFAULT_BUFSIZE = 256; ACE_Section_Key_Win32::ACE_Section_Key_Win32 (HKEY hKey) : hKey_ (hKey) { add_ref (); } ACE_Section_Key_Win32::~ACE_Section_Key_Win32 (void) { ::RegCloseKey (hKey_); } ////////////////////////////////////////////////////////////////////////////// ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry (HKEY hKey) { ACE_Section_Key_Win32 *temp; ACE_NEW (temp, ACE_Section_Key_Win32 (hKey)); root_ = ACE_Configuration_Section_Key (temp); } ACE_Configuration_Win32Registry::~ACE_Configuration_Win32Registry (void) { } int ACE_Configuration_Win32Registry::open_section (const ACE_Configuration_Section_Key& base, const TCHAR* sub_section, int create, ACE_Configuration_Section_Key& result) { if (validate_name (sub_section)) return -1; HKEY base_key; if (load_key (base, base_key)) return -1; HKEY result_key; if (::RegOpenKeyEx (base_key, sub_section, 0, KEY_ALL_ACCESS, &result_key) != ERROR_SUCCESS) { if (!create) return -2; if (::RegCreateKeyEx (base_key, sub_section, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &result_key, NULL) != ERROR_SUCCESS) return -3; } ACE_Section_Key_Win32 *temp; ACE_NEW_RETURN (temp, ACE_Section_Key_Win32 (result_key), -4); result = ACE_Configuration_Section_Key (temp); return 0; } int ACE_Configuration_Win32Registry::remove_section (const ACE_Configuration_Section_Key& key, const TCHAR* sub_section, int recursive) { if (validate_name (sub_section)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; if (recursive) { ACE_Configuration_Section_Key section; if (open_section (key, sub_section, 0, section)) return -2; HKEY sub_key; if (load_key (section, sub_key)) return -3; TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; DWORD buffer_size = ACE_DEFAULT_BUFSIZE; // Note we don't increment the index because the // enumeration becomes invalid if we change the // subkey, which we do when we delete it. By leaving // it 0, we always delete the top entry while (::RegEnumKeyEx (sub_key, 0, name_buffer, &buffer_size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { remove_section (section, name_buffer, 1); buffer_size = ACE_DEFAULT_BUFSIZE; } } if (::RegDeleteKey (base_key, sub_section) != ERROR_SUCCESS) return -2; return 0; } int ACE_Configuration_Win32Registry::enumerate_values (const ACE_Configuration_Section_Key& key, int Index, ACE_TString& name, VALUETYPE& type) { HKEY base_key; if (load_key (key, base_key)) return -1; TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; DWORD buffer_size = ACE_DEFAULT_BUFSIZE; DWORD value_type; if (::RegEnumValue (base_key, Index, name_buffer, &buffer_size, NULL, &value_type, NULL, NULL) != ERROR_SUCCESS) return -2; name = name_buffer; switch (value_type) { case REG_BINARY: type = BINARY; break; case REG_SZ: type = STRING; break; case REG_DWORD: type = INTEGER; break; default: type = INVALID; } return 0; } int ACE_Configuration_Win32Registry::enumerate_sections (const ACE_Configuration_Section_Key& key, int Index, ACE_TString& name) { HKEY base_key; if (load_key (key, base_key)) return -1; TCHAR name_buffer[ACE_DEFAULT_BUFSIZE]; DWORD buffer_size = ACE_DEFAULT_BUFSIZE; if (::RegEnumKeyEx (base_key, Index, name_buffer, &buffer_size, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) return -2; name = name_buffer; return 0; } int ACE_Configuration_Win32Registry::set_string_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, const ACE_TString& value) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; if (::RegSetValueEx (base_key, name, 0, REG_SZ, (BYTE *) value.rep (), value.length () + 1) != ERROR_SUCCESS) return -2; return 0; } int ACE_Configuration_Win32Registry::set_integer_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, u_int value) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; if (::RegSetValueEx (base_key, name, 0, REG_DWORD, (BYTE *) &value, sizeof (value)) != ERROR_SUCCESS) return -2; return 0; } int ACE_Configuration_Win32Registry::set_binary_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, const void* data, u_int length) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; if (::RegSetValueEx (base_key, name, 0, REG_BINARY, (BYTE*)data, length) != ERROR_SUCCESS) return -2; return 0; } int ACE_Configuration_Win32Registry::get_string_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, ACE_TString& value) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; TCHAR buffer[ACE_DEFAULT_BUFSIZE]; DWORD length = ACE_DEFAULT_BUFSIZE; DWORD type; if (::RegQueryValueEx (base_key, name, NULL, &type, (BYTE*)buffer, &length) != ERROR_SUCCESS) return -2; if (type != REG_SZ) return -3; value = buffer; return 0; } int ACE_Configuration_Win32Registry::get_integer_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, u_int& value) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; DWORD length = sizeof (value); DWORD type; if (::RegQueryValueEx (base_key, name, NULL, &type, (BYTE*)&value, &length) != ERROR_SUCCESS) return -2; if (type != REG_DWORD) return -3; return 0; } int ACE_Configuration_Win32Registry::get_binary_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, void*& data, u_int& length) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; unsigned char buffer[ACE_DEFAULT_BUFSIZE]; DWORD buffer_length = ACE_DEFAULT_BUFSIZE; DWORD type; if (::RegQueryValueEx (base_key, name, NULL, &type, (BYTE*)&buffer, &buffer_length) != ERROR_SUCCESS) return -2; if (type != REG_BINARY) return -3; length = buffer_length; char* new_data; ACE_NEW_RETURN (new_data, char[length], -4); ACE_OS::memcpy (new_data, buffer, length); data = new_data; return 0; } int ACE_Configuration_Win32Registry::remove_value (const ACE_Configuration_Section_Key& key, const TCHAR* name) { if (validate_name (name)) return -1; HKEY base_key; if (load_key (key, base_key)) return -1; if (::RegDeleteValue (base_key, name) != ERROR_SUCCESS) return -2; return 0; } int ACE_Configuration_Win32Registry::load_key (const ACE_Configuration_Section_Key& key, HKEY& hKey) { ACE_Section_Key_Win32* pKey = ACE_dynamic_cast (ACE_Section_Key_Win32*, get_internal_key (key)); if (!pKey) return -1; hKey = pKey->hKey_; return 0; } HKEY ACE_Configuration_Win32Registry::resolve_key (HKEY hKey, const TCHAR* path, int create) { const TCHAR* begin = path; const TCHAR* end = 0; HKEY result = 0; // Make a copy of hKey if (::RegOpenKey (hKey, NULL, &result) != ERROR_SUCCESS) return 0; // recurse through the path while (1) { // Detmine the begin/ending of the key name end = ACE_OS::strchr (begin, '\\'); size_t length = end ? (size_t)(end-begin) : ACE_OS::strlen (begin); // Make sure length is not 0 if (!length) return 0; // Open the key ACE_TString key (begin, length); HKEY subkey; if (::RegOpenKey (result, key.rep (), &subkey) != ERROR_SUCCESS) { // try creating it if (!create || ::RegCreateKeyEx (result, key.rep (), NULL, NULL, NULL, KEY_ALL_ACCESS, NULL, &subkey, NULL) != ERROR_SUCCESS) { // error ::RegCloseKey (result); return 0; } } // release our open key handle ::RegCloseKey (result); result = subkey; // If end is NULL, we are done, return the result if (!end) return result; begin = end + 1; } return 0; } #endif // WIN_32 /////////////////////////////////////////////////////////////// ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void) : type_ (ACE_Configuration::INVALID), data_ (0), length_ (0) { } ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (TCHAR* string) : type_ (ACE_Configuration::STRING), data_ (string), length_ (0) { } ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (u_int integer) : type_ (ACE_Configuration::INTEGER), data_ ((void*) integer), length_ (0) { } ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void* data, u_int length) : type_ (ACE_Configuration::BINARY), data_ (data), length_ (length) { } ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (const ACE_Configuration_Value_IntId& rhs) : type_ (rhs.type_), data_ (rhs.data_), length_ (rhs.length_) { } ACE_Configuration_Value_IntId::~ACE_Configuration_Value_IntId (void) { } ACE_Configuration_Value_IntId& ACE_Configuration_Value_IntId::operator= (const ACE_Configuration_Value_IntId& rhs) { if (this != &rhs) { type_ = rhs.type_; data_ = rhs.data_; length_ = rhs.length_; } return *this; } void ACE_Configuration_Value_IntId::free (ACE_Allocator* allocator) { switch (type_) { case ACE_Configuration::STRING: case ACE_Configuration::BINARY: allocator->free ((void *) (data_)); break; case ACE_Configuration::INTEGER: case ACE_Configuration::INVALID: // Do nothing break; } } ///////////////////////////////////////////////////////////////////////////// ACE_Configuration_ExtId::ACE_Configuration_ExtId (void) : name_ (0) { } ACE_Configuration_ExtId::ACE_Configuration_ExtId (const TCHAR* name) : name_ (name) { } ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_Configuration_ExtId& rhs) : name_ (rhs.name_) { } ACE_Configuration_ExtId::~ACE_Configuration_ExtId (void) { } ACE_Configuration_ExtId& ACE_Configuration_ExtId::operator= (const ACE_Configuration_ExtId& rhs) { if (this != &rhs) name_ = rhs.name_; return *this; } int ACE_Configuration_ExtId::operator == (const ACE_Configuration_ExtId& rhs) const { return (ACE_OS::strcmp (name_, rhs.name_) == 0); } int ACE_Configuration_ExtId::operator != (const ACE_Configuration_ExtId& rhs) const { return (ACE_OS::strcmp (name_, rhs.name_) != 0); } u_long ACE_Configuration_ExtId::hash (void) const { ACE_TString temp (name_); return temp.hash (); } const TCHAR* ACE_Configuration_ExtId::name (void) { return name_; } void ACE_Configuration_ExtId::free (ACE_Allocator* allocator) { allocator->free ((void *) (name_)); } /////////////////////////////////////////////////////////////////////// ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (void) : value_hash_map_ (0), section_hash_map_ (0) { } ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (VALUE_MAP* value_hash_map, SUBSECTION_MAP* section_hash_map) : value_hash_map_ (value_hash_map), section_hash_map_ (section_hash_map) { } ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (const ACE_Configuration_Section_IntId& rhs) : value_hash_map_ (rhs.value_hash_map_), section_hash_map_ (rhs.section_hash_map_) { } ACE_Configuration_Section_IntId::~ACE_Configuration_Section_IntId () { } ACE_Configuration_Section_IntId& ACE_Configuration_Section_IntId::operator= (const ACE_Configuration_Section_IntId& rhs) { if (this != &rhs) { value_hash_map_ = rhs.value_hash_map_; section_hash_map_ = rhs.section_hash_map_; } return *this; } void ACE_Configuration_Section_IntId::free (ACE_Allocator* allocator) { allocator->free ((void *)(value_hash_map_)); allocator->free ((void *)(section_hash_map_)); } ACE_Configuration_Section_Key_Heap::ACE_Configuration_Section_Key_Heap (const TCHAR* path) : path_ (0), value_iter_ (0), section_iter_ (0) { path_ = ACE_OS::strdup (path); } ACE_Configuration_Section_Key_Heap::~ACE_Configuration_Section_Key_Heap () { delete value_iter_; delete section_iter_; ACE_OS::free (path_); } ////////////////////////////////////////////////////////////////////////////// ACE_Configuration_Heap::ACE_Configuration_Heap (void) : allocator_ (0), index_ (0), default_map_size_ (0) { ACE_Configuration_Section_Key_Heap *temp = 0; ACE_NEW (temp, ACE_Configuration_Section_Key_Heap (ACE_TEXT (""))); root_ = ACE_Configuration_Section_Key (temp); } ACE_Configuration_Heap::~ACE_Configuration_Heap (void) { if (allocator_) allocator_->sync (); delete allocator_; } int ACE_Configuration_Heap::open (int default_map_size) { default_map_size_ = default_map_size; // Create the allocator with the appropriate options. // The name used for the lock is the same as one used // for the file. ACE_NEW_RETURN (this->allocator_, HEAP_ALLOCATOR (), -1); return create_index (); } int ACE_Configuration_Heap::open (const TCHAR* file_name, void* base_address, int default_map_size) { default_map_size_ = default_map_size; // Make sure that the file name is of the legal length. if (ACE_OS::strlen (file_name) >= MAXNAMELEN + MAXPATHLEN) { errno = ENAMETOOLONG; return -1; } #if !defined (CHORUS) ACE_MMAP_Memory_Pool::OPTIONS options (base_address); #else // Use base address == 0, don't use a fixed address. ACE_MMAP_Memory_Pool::OPTIONS options (0, 0, 0, ACE_CHORUS_LOCAL_NAME_SPACE_T_SIZE); #endif /* CHORUS */ // Create the allocator with the appropriate options. The name used // for the lock is the same as one used for the file. ACE_NEW_RETURN (this->allocator_, PERSISTENT_ALLOCATOR (file_name, file_name, &options), -1); #if !defined (ACE_LACKS_ACCESS) // Now check if the backing store has been created successfully. if (ACE_OS::access (file_name, F_OK) != 0) ACE_ERROR_RETURN ((LM_ERROR, ASYS_TEXT ("create_index\n")), -1); #endif /* ACE_LACKS_ACCESS */ return create_index (); } int ACE_Configuration_Heap::create_index (void) { void *section_index = 0; // This is the easy case since if we find hash table in the // memory-mapped file we know it's already initialized. if (this->allocator_->find (ACE_CONFIG_SECTION_INDEX, section_index) == 0) this->index_ = (SECTION_MAP *) section_index; // Create a new (because we've just created a new // memory-mapped file). else { size_t index_size = sizeof (SECTION_MAP); section_index = this->allocator_->malloc (index_size); if (section_index == 0 || create_index_helper (section_index) == -1 || this->allocator_->bind (ACE_CONFIG_SECTION_INDEX, section_index) == -1) { // Attempt to clean up. ACE_ERROR ((LM_ERROR, ASYS_TEXT("create_index\n"))); this->allocator_->remove (); return -1; } // Add the root section return new_section (ACE_TEXT (""), root_); } return 0; } int ACE_Configuration_Heap::create_index_helper (void *buffer) { ACE_NEW_RETURN (this->index_, (buffer) SECTION_MAP (this->allocator_), -1); return 0; } int ACE_Configuration_Heap::load_key (const ACE_Configuration_Section_Key& key, ACE_TString& name) { ACE_Configuration_Section_Key_Heap* pKey = ACE_dynamic_cast (ACE_Configuration_Section_Key_Heap*, get_internal_key (key)); if (!pKey) return -1; name = pKey->path_; return 0; } int ACE_Configuration_Heap::add_section (const ACE_Configuration_Section_Key& base, const TCHAR* sub_section, ACE_Configuration_Section_Key& result) { ACE_TString section; if (load_key (base, section)) return -1; // Find the base section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // See if this section already exists ACE_Configuration_ExtId SubSectionExtId (sub_section); int ignored = 0; if (!IntId.section_hash_map_->find (SubSectionExtId, ignored, allocator_)) // already exists! return -3; // Create the new section name // only prepend a separater if were not at the root if (section.length ()) section += "\\"; section += sub_section; // Add it to the base section TCHAR* pers_name = (TCHAR*)allocator_->malloc ((ACE_OS::strlen (sub_section) + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_name, sub_section); ACE_Configuration_ExtId SSExtId (pers_name); if (IntId.section_hash_map_->bind (SSExtId, ignored, allocator_)) { allocator_->free (pers_name); return -4; } return (new_section (section, result)); } int ACE_Configuration_Heap::new_section (const ACE_TString& section, ACE_Configuration_Section_Key& result) { // Create a new section and add it to the global list // Allocate memory for items to be stored in the table. size_t section_len = section.length () + 1; TCHAR *ptr = (TCHAR*) this->allocator_->malloc (section_len); int return_value = -1; if (ptr == 0) return -1; else { // Populate memory with data. ACE_OS::strcpy (ptr, section.rep ()); void *value_hash_map = 0; size_t map_size = sizeof (VALUE_MAP); value_hash_map = this->allocator_->malloc (map_size); // If allocation failed ... if (value_hash_map == 0) return -1; // Initialize allocated hash map through placement new. if (value_open_helper (default_map_size_, value_hash_map ) == -1) { this->allocator_->free (value_hash_map ); return -2; } // create the section map void* section_hash_map = 0; map_size = sizeof (SUBSECTION_MAP); section_hash_map = this->allocator_->malloc (map_size); // If allocation failed if (section_hash_map == 0) return -1; // initialize allocated hash map through placement new if (section_open_helper (default_map_size_, section_hash_map) == -1) { this->allocator_->free (value_hash_map ); this->allocator_->free (section_hash_map); return -2; } ACE_Configuration_ExtId name (ptr); ACE_Configuration_Section_IntId entry ((VALUE_MAP*)value_hash_map , (SUBSECTION_MAP*)section_hash_map); // Do a normal bind. This will fail if there's already an // entry with the same name. return_value = this->index_->bind (name, entry, this->allocator_); if (return_value == 1) { // Entry already existed so bind failed. Free our dynamically // allocated memory. this->allocator_->free ((void *) ptr); return return_value; } if (return_value == -1) // Free our dynamically allocated memory. this->allocator_->free ((void *) ptr); else // If bind() succeed, it will automatically sync // up the map manager entry. However, we must sync up our // name/value memory. this->allocator_->sync (ptr, section_len); } // set the result ACE_Configuration_Section_Key_Heap *temp; ACE_NEW_RETURN (temp, ACE_Configuration_Section_Key_Heap (section.rep ()), -2); result = ACE_Configuration_Section_Key (temp); return return_value; } int ACE_Configuration_Heap::value_open_helper (size_t hash_table_size, void *buffer) { ACE_NEW_RETURN (buffer, (buffer) VALUE_MAP (hash_table_size, this->allocator_), -1); return 0; } int ACE_Configuration_Heap::section_open_helper (size_t hash_table_size, void *buffer) { ACE_NEW_RETURN (buffer, (buffer) SUBSECTION_MAP (hash_table_size, this->allocator_), -1); return 0; } int ACE_Configuration_Heap::open_section (const ACE_Configuration_Section_Key& base, const TCHAR* sub_section, int create, ACE_Configuration_Section_Key& result) { if (validate_name (sub_section)) return -1; ACE_TString section; if (load_key (base, section)) return -1; // Only add the \\ if were not at the root if (section.length ()) section += ACE_TEXT ("\\"); section += sub_section; // resolve the section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) { if (!create) return -2; return add_section (base, sub_section, result); } ACE_Configuration_Section_Key_Heap *temp; ACE_NEW_RETURN (temp, ACE_Configuration_Section_Key_Heap (section.rep ()), -3); result = ACE_Configuration_Section_Key (temp); return 0; } int ACE_Configuration_Heap::remove_section (const ACE_Configuration_Section_Key& key, const TCHAR* sub_section, int recursive) { if (validate_name (sub_section)) return -1; ACE_TString section; if (load_key (key, section)) return -1; // Find this key ACE_Configuration_ExtId ParentExtId (section.rep ()); ACE_Configuration_Section_IntId ParentIntId; if (index_->find (ParentExtId, ParentIntId, allocator_)) return -2;// no parent key // Find this subkey if (section.length ()) section += ACE_TEXT ("\\"); section += sub_section; ACE_Configuration_ExtId SectionExtId (section.rep ()); SECTION_ENTRY* section_entry; SECTION_HASH* hashmap = index_; if (hashmap->find (SectionExtId, section_entry)) return -2; if (recursive) { ACE_Configuration_Section_Key section; if (open_section (key, sub_section, 0, section)) return -3; int index = 0; ACE_TString name; while (!enumerate_sections (section, index, name)) { if (remove_section (section, name.rep (), 1)) return -4; index++; } } // Now make sure we dont have any subkeys if (section_entry->int_id_.section_hash_map_->current_size ()) return -3; // Now remove subkey from parent key ACE_Configuration_ExtId SubSExtId (sub_section); SUBSECTION_ENTRY* subsection_entry; if (((SUBSECTION_HASH*)ParentIntId.section_hash_map_)-> find (SubSExtId, subsection_entry)) return -4; if (ParentIntId.section_hash_map_->unbind (SubSExtId, allocator_)) return -5; subsection_entry->ext_id_.free (allocator_); // Remember the pointers so we can free them after we unbind ACE_Configuration_ExtId ExtIdToFree (section_entry->ext_id_); ACE_Configuration_Section_IntId IntIdToFree (section_entry->int_id_); // iterate over all values and free memory VALUE_HASH* value_hash_map = section_entry->int_id_.value_hash_map_; VALUE_HASH::ITERATOR value_iter = value_hash_map->begin (); while (!value_iter.done ()) { VALUE_ENTRY* value_entry; if (!value_iter.next (value_entry)) return 1; value_entry->ext_id_.free (allocator_); value_entry->int_id_.free (allocator_); value_iter.advance (); } // remove it if (index_->unbind (SectionExtId, allocator_)) return -5; // Free the memory ExtIdToFree.free (allocator_); IntIdToFree.free (allocator_); return 0; } int ACE_Configuration_Heap::enumerate_values (const ACE_Configuration_Section_Key& key, int index, ACE_TString& name, VALUETYPE& type) { ACE_Configuration_Section_Key_Heap* pKey = ACE_dynamic_cast (ACE_Configuration_Section_Key_Heap*, get_internal_key (key)); if (!pKey) return -1; name = pKey->path_; // resolve the section ACE_Configuration_ExtId ExtId (pKey->path_); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // Handle iterator resets if (index == 0) { ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex>* hash_map = IntId.value_hash_map_; // @@ This zero pointer check is redundant -Ossama // if (pKey->value_iter_) delete pKey->value_iter_; ACE_NEW_RETURN (pKey->value_iter_, VALUE_HASH::ITERATOR(hash_map->begin()), -3); } // Get the next entry ACE_Hash_Map_Entry* entry; if (!pKey->value_iter_->next (entry)) return 1; // Return the value of the iterator and advance it name = entry->ext_id_.name_; type = entry->int_id_.type_; pKey->value_iter_->advance (); return 0; } int ACE_Configuration_Heap::enumerate_sections (const ACE_Configuration_Section_Key& key, int index, ACE_TString& name) { // cast to a heap section key ACE_Configuration_Section_Key_Heap* pKey = ACE_dynamic_cast (ACE_Configuration_Section_Key_Heap*, get_internal_key (key)); if (!pKey) return -1; // not a heap key! // resolve the section ACE_Configuration_ExtId ExtId (pKey->path_); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // unknown section // Handle iterator resets if (index == 0) { if (pKey->section_iter_) delete pKey->section_iter_; ACE_NEW_RETURN (pKey->section_iter_, SUBSECTION_HASH::ITERATOR (IntId.section_hash_map_->begin ()), -3); } // Get the next entry ACE_Hash_Map_Entry* entry; if (!pKey->section_iter_->next (entry)) return 1; // Return the value of the iterator and advance it pKey->section_iter_->advance (); name = entry->ext_id_.name_; return 0; } int ACE_Configuration_Heap::set_string_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, const ACE_TString& value) { if (validate_name (name)) return -1; ACE_TString section; if (load_key (key, section)) return -1; ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; ACE_Configuration_ExtId VExtIdFind (name); ACE_Configuration_Value_IntId VIntIdFind; // See if it exists first if (IntId.value_hash_map_->find (VExtIdFind, VIntIdFind, allocator_)) { // it doesn't exist, bind it TCHAR* pers_name = (TCHAR*)allocator_->malloc ((ACE_OS::strlen (name) + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_name, name); TCHAR* pers_value = (TCHAR*)allocator_->malloc ((value.length () + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_value, value.rep ()); ACE_Configuration_ExtId VExtId (pers_name); ACE_Configuration_Value_IntId VIntId (pers_value); if (IntId.value_hash_map_->bind (VExtId, VIntId, allocator_)) { allocator_->free (pers_value); allocator_->free (pers_name); return -3; } return 0; } else { // Free the old value memory VIntIdFind.free (allocator_); // Assign a new value TCHAR* pers_value = (TCHAR*)allocator_->malloc ((value.length () + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_value, value.rep ()); VIntIdFind = ACE_Configuration_Value_IntId (pers_value); } return 0; } int ACE_Configuration_Heap::set_integer_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, u_int value) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist // See if it exists first ACE_Configuration_ExtId VExtId (name); ACE_Configuration_Value_IntId VIntId; if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) { // it doesn't exist, bind it TCHAR* pers_name = (TCHAR*)allocator_->malloc ((ACE_OS::strlen (name) + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_name, name); ACE_Configuration_ExtId VExtId (pers_name); ACE_Configuration_Value_IntId VIntId (value); if (IntId.value_hash_map_->bind (VExtId, VIntId, allocator_)) return -3; return 0; } else { // rebind it VIntId = ACE_Configuration_Value_IntId (value); } return 0; } int ACE_Configuration_Heap::set_binary_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, const void* data, u_int length) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist // See if the value exists first ACE_Configuration_ExtId VExtIdFind (name); ACE_Configuration_Value_IntId VIntIdFind; if (IntId.value_hash_map_->find (VExtIdFind, VIntIdFind, allocator_)) { // it doesn't exist, bind it TCHAR* pers_name = (TCHAR*)allocator_->malloc ((ACE_OS::strlen (name) + 1) * sizeof (TCHAR)); ACE_OS::strcpy (pers_name, name); TCHAR* pers_value = (TCHAR*)allocator_->malloc (length); ACE_OS::memcpy (pers_value, data, length); ACE_Configuration_ExtId VExtId (pers_name); ACE_Configuration_Value_IntId VIntId (pers_value, length); if (IntId.value_hash_map_->bind (VExtId, VIntId, allocator_)) { allocator_->free (pers_value); allocator_->free (pers_name); return -3; } return 0; } else { // it does exist, free the old value memory VIntIdFind.free (allocator_); // Assign a new value TCHAR* pers_value = (TCHAR*)allocator_->malloc (length); ACE_OS::memcpy (pers_value, data, length); VIntIdFind = ACE_Configuration_Value_IntId (pers_value, length); } return 0; } int ACE_Configuration_Heap::get_string_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, ACE_TString& value) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist // See if it exists first ACE_Configuration_ExtId VExtId (name); ACE_Configuration_Value_IntId VIntId; if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) return -3; // unknown value // Check type if (VIntId.type_ != ACE_Configuration::STRING) return -4; // everythings ok, return the data value = (TCHAR*)VIntId.data_; return 0; } int ACE_Configuration_Heap::get_integer_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, u_int& value) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist // See if it exists first ACE_Configuration_ExtId VExtId (name); ACE_Configuration_Value_IntId VIntId; if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) return -3; // unknown value // Check type if (VIntId.type_ != ACE_Configuration::INTEGER) return -4; // Everythings ok, return the data value = (u_int)((long)VIntId.data_); return 0; } int ACE_Configuration_Heap::get_binary_value (const ACE_Configuration_Section_Key& key, const TCHAR* name, void*& data, u_int& length) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist ACE_Configuration_ExtId VExtId (name); ACE_Configuration_Value_IntId VIntId; // See if it exists first if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_)) return -3; // unknown value // Check type if (VIntId.type_ != ACE_Configuration::BINARY) return -4; // Make a copy ACE_NEW_RETURN (data, char[VIntId.length_], -5); ACE_OS::memcpy (data, VIntId.data_, VIntId.length_); length = VIntId.length_; return 0; } int ACE_Configuration_Heap::remove_value (const ACE_Configuration_Section_Key& key, const TCHAR* name) { if (validate_name (name)) return -1; // Get the section name from the key ACE_TString section; if (load_key (key, section)) return -1; // Find this section ACE_Configuration_ExtId ExtId (section.rep ()); ACE_Configuration_Section_IntId IntId; if (index_->find (ExtId, IntId, allocator_)) return -2; // section does not exist // Find it ACE_Configuration_ExtId ValueExtId (name); VALUE_ENTRY* value_entry; if (((VALUE_HASH*)IntId.value_hash_map_)->find (ValueExtId, value_entry)) return -4; // free it value_entry->ext_id_.free (allocator_); value_entry->int_id_.free (allocator_); // Unbind it if (IntId.value_hash_map_->unbind (ValueExtId, allocator_)) return -3; return 0; } #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) #if defined (ACE_HAS_THREADS) // ACE_SYNCH_MUTEX should not be used in the template instantiations // because the resulting template instantiation for the // single-threaded case already exists in ACE. template class ACE_Allocator_Adapter >; template class ACE_Malloc; template class ACE_Malloc_T; #endif /* ACE_HAS_THREADS */ template class ACE_Hash_Map_Entry; template class ACE_Hash_Map_Entry; template class ACE_Hash_Map_Entry; template class ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex>; // Added to fix problems in SunOS CC5.0 template class ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Equal_To; template class ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex>; template class ACE_Hash; template class ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Manager; template class ACE_Hash_Map_Manager; template class ACE_Hash_Map_Manager; template class ACE_Hash_Map_With_Allocator; template class ACE_Hash_Map_With_Allocator; template class ACE_Hash_Map_With_Allocator; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #if defined (ACE_HAS_THREADS) // ACE_SYNCH_MUTEX should not be used in the template instantiations // because the resulting template instantiation for the // single-threaded case already exists in ACE. #pragma instantiate ACE_Allocator_Adapter > #pragma instantiate ACE_Malloc #pragma instantiate ACE_Malloc_T #endif /* ACE_HAS_THREADS */ #pragma instantiate ACE_Hash_Map_Entry #pragma instantiate ACE_Hash_Map_Entry #pragma instantiate ACE_Hash_Map_Entry #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Equal_To #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex,ACE_Equal_To,ACE_Null_Mutex> #pragma instantiate ACE_Hash #pragma instantiate ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Manager #pragma instantiate ACE_Hash_Map_Manager #pragma instantiate ACE_Hash_Map_Manager #pragma instantiate ACE_Hash_Map_With_Allocator #pragma instantiate ACE_Hash_Map_With_Allocator #pragma instantiate ACE_Hash_Map_With_Allocator #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */