diff options
author | brunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-11-11 05:36:09 +0000 |
---|---|---|
committer | brunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-11-11 05:36:09 +0000 |
commit | 94997be48ecf0d04ae60d9d23331876a985d7114 (patch) | |
tree | 5f5ccffb5fbc57310b9fd2af0f0b730460335b9c /ace/Configuration.cpp | |
parent | fab28322dfcd424f569f36b2bb1312123a6f6219 (diff) | |
download | ATCD-94997be48ecf0d04ae60d9d23331876a985d7114.tar.gz |
ChangeLogTag:Wed Nov 10 23:29:25 1999 Darrell Brunsch <brunsch@cs.wustl.edu>
Diffstat (limited to 'ace/Configuration.cpp')
-rw-r--r-- | ace/Configuration.cpp | 1940 |
1 files changed, 1940 insertions, 0 deletions
diff --git a/ace/Configuration.cpp b/ace/Configuration.cpp new file mode 100644 index 00000000000..7921292f415 --- /dev/null +++ b/ace/Configuration.cpp @@ -0,0 +1,1940 @@ +// $Id$ +#define ACE_BUILD_DLL +#include "ACE/Configuration.h" +#if defined(ACE_WIN32) +#include <windows.h> +#endif // ACE_WIN32 + +#if !defined (__ACE_INLINE__) +#include "ace/Configuration.i" +#endif /* __ACE_INLINE__ */ + +#define DEFBUFSIZE 256 + + +/////////////////////////////////////////////////////////////// + +ACE_Section_Key_Internal::ACE_Section_Key_Internal() +: ref_count_(0) +{ +} + +ACE_Section_Key_Internal::~ACE_Section_Key_Internal() +{ +} + +int ACE_Section_Key_Internal::add_ref() +{ + ++ref_count_; + return 0; +} + +int ACE_Section_Key_Internal::dec_ref() +{ + if(!--ref_count_) + { + delete this; + } + return 0; +} + +/////////////////////////////////////////////////////////////// + +ACE_Configuration_Section_Key::ACE_Configuration_Section_Key() +: key_(0) +{ +} + +ACE_Configuration_Section_Key::~ACE_Configuration_Section_Key() +{ + 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() +{ +} + +ACE_Configuration::~ACE_Configuration() +{ +} + +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 ASYS_TCHAR* begin = path_in.rep(); + const ASYS_TCHAR* end = 0; + + // Make a copy of key + ACE_Configuration_Section_Key current_section = key; + + // recurse through the path + while(true) + { + // 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; + return 0; + } + begin = end + 1; + } + return -1; +} + +int ACE_Configuration::validate_name(const ASYS_TCHAR* name) +{ + const ASYS_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 = "["; + header += path; + header += "]"; + header +="\n"; + if(ACE_OS::fputs(header.rep(), out) < 0) + { + return -1; + } + + // Write out each value + int index = 0; + ACE_TString name; + VALUETYPE type; + ACE_TString line; + ASYS_TCHAR int_value[32]; + ACE_TString string_value; + while(!enumerate_values(section, index, name, type)) + { + line = name + "="; + switch(type) + { + case INTEGER: + { + unsigned int value; + if(get_integer_value(section, name.rep(), value)) + { + return -2; + } + ACE_OS::sprintf(int_value, "#%d", value); + line += int_value; + break; + } + case STRING: + { + if(get_string_value( + section, + name.rep(), + string_value)) + { + return -2; + } + line += "\""; + line += string_value; + break; + } + case BINARY: + { + // not supported yet - maybe use BASE64 codeing? + break; + } + default: + return -3; + } + line+="\n"; + if(ACE_OS::fputs(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 += "\\"; + } + 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(const ASYS_TCHAR* filename) +{ + FILE* out = ACE_OS::fopen(filename, "w"); + if(!out) + { + return -1; + } + + int result = export_section(root_, "", out); + ACE_OS::fclose(out); + return result; +} + +int ACE_Configuration::import(const ASYS_TCHAR* filename) +{ + FILE* in = ACE_OS::fopen(filename, "r"); + if(!in) + { + return -1; + } + + // XXX - change this to a dynamic buffer + ASYS_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 + ASYS_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 + unsigned int value = atoi(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() +{ + return root_; +} + +////////////////////////////////////////////////////////////////////////////// + +#if defined(WIN32) + +ACE_Section_Key_Win32::ACE_Section_Key_Win32(HKEY hKey) +: hKey_(hKey) +{ + add_ref(); +} + +ACE_Section_Key_Win32::~ACE_Section_Key_Win32() +{ + ::RegCloseKey(hKey_); +} + +////////////////////////////////////////////////////////////////////////////// + +ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry(HKEY hKey) +{ + root_ = ACE_Configuration_Section_Key( + new ACE_Section_Key_Win32(hKey)); +} + + +ACE_Configuration_Win32Registry::~ACE_Configuration_Win32Registry() +{ +} + +int ACE_Configuration_Win32Registry::open_section( + const ACE_Configuration_Section_Key& base, + const ASYS_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; + } + } + result = ACE_Configuration_Section_Key( + new ACE_Section_Key_Win32(result_key)); + return 0; +} + +int +ACE_Configuration_Win32Registry::remove_section( + const ACE_Configuration_Section_Key& key, + const ASYS_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; + } + + ASYS_TCHAR name_buffer[DEFBUFSIZE]; + DWORD buffer_size = DEFBUFSIZE; + // 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 = DEFBUFSIZE; + } + } + 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; + } + ASYS_TCHAR name_buffer[DEFBUFSIZE]; + DWORD buffer_size = DEFBUFSIZE; + 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; + } + ASYS_TCHAR name_buffer[DEFBUFSIZE]; + DWORD buffer_size = DEFBUFSIZE; + 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 ASYS_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()) != ERROR_SUCCESS) + { + return -2; + } + + return 0; +} + +int ACE_Configuration_Win32Registry::set_integer_value( + const ACE_Configuration_Section_Key& key, + const ASYS_TCHAR* name, + unsigned 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 ASYS_TCHAR* name, + const void* data, + unsigned 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 ASYS_TCHAR* name, + ACE_TString& value) +{ + if(validate_name(name)) + { + return -1; + } + HKEY base_key; + if(load_key(key, base_key)) + { + return -1; + } + + ASYS_TCHAR buffer[DEFBUFSIZE]; + DWORD length = DEFBUFSIZE; + 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 ASYS_TCHAR* name, + unsigned 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 ASYS_TCHAR* name, + void*& data, + unsigned int& length) +{ + if(validate_name(name)) + { + return -1; + } + HKEY base_key; + if(load_key(key, base_key)) + { + return -1; + } + + unsigned char buffer[DEFBUFSIZE]; + DWORD buffer_length = DEFBUFSIZE; + 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 = new char[length]; + memcpy(new_data, buffer, length); + data = new_data; + return 0; +} + +int ACE_Configuration_Win32Registry::remove_value( + const ACE_Configuration_Section_Key& key, + const ASYS_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 ASYS_TCHAR* path, + int create) +{ + const ASYS_TCHAR* begin = path; + const ASYS_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(true) + { + // 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(ASYS_TCHAR* string) +: type_(ACE_Configuration::STRING), data_(string), length_(0) +{ +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId(unsigned int integer) +: type_(ACE_Configuration::INTEGER), data_((void*)integer), length_(0) +{ +} + +ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId(void* data, unsigned 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_)); + } +} + +///////////////////////////////////////////////////////////////////////////// + +ACE_Configuration_ExtId::ACE_Configuration_ExtId(void) +: name_(0) +{ +} + +ACE_Configuration_ExtId::ACE_Configuration_ExtId(const ASYS_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 ASYS_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 ASYS_TCHAR* path) +: 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_; + delete path_; +} + +////////////////////////////////////////////////////////////////////////////// + +ACE_Configuration_Heap::ACE_Configuration_Heap(void) +{ + root_ = ACE_Configuration_Section_Key( + new ACE_Configuration_Section_Key_Heap(ACE_TEXT(""))); +} + +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 ASYS_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, + ACE_TEXT("create_index\n")), + -1); +#endif /* ACE_LACKS_ACCESS */ + + return create_index(); +} + +int ACE_Configuration_Heap::create_index() +{ + 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 <index_> (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, + ACE_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 ASYS_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 + ASYS_TCHAR* pers_name = (ASYS_TCHAR*)allocator_->malloc( + (ACE_OS::strlen(sub_section) + 1) * sizeof(ASYS_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; + ASYS_TCHAR *ptr = (ASYS_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 + result = ACE_Configuration_Section_Key( + new ACE_Configuration_Section_Key_Heap(section.rep())); + 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 ASYS_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 += "\\"; + } + 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); + } + + result = ACE_Configuration_Section_Key( + new ACE_Configuration_Section_Key_Heap(section.rep())); + + return 0; +} + +int ACE_Configuration_Heap::remove_section( + const ACE_Configuration_Section_Key& key, + const ASYS_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_)) + { + // no parent key + return -2; + } + + // Find this subkey + if(section.length()) + { + section += "\\"; + } + 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_Configuration_ExtId , ACE_Configuration_Value_IntId, ACE_Hash<ACE_Configuration_ExtId>, ACE_Equal_To<ACE_Configuration_ExtId>, ACE_Null_Mutex>* hash_map = IntId.value_hash_map_; + if(pKey->value_iter_) + { + delete pKey->value_iter_; + } + pKey->value_iter_ = new ACE_Hash_Map_Manager_Ex<ACE_Configuration_ExtId , ACE_Configuration_Value_IntId, ACE_Hash<ACE_Configuration_ExtId>, ACE_Equal_To<ACE_Configuration_ExtId>, ACE_Null_Mutex>::ITERATOR(hash_map->begin()); + } + + // Get the next entry + ACE_Hash_Map_Entry<ACE_Configuration_ExtId, ACE_Configuration_Value_IntId>* 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) + { + // not a heap key! + return -1; + } + + // resolve the section + ACE_Configuration_ExtId ExtId(pKey->path_); + ACE_Configuration_Section_IntId IntId; + if(index_->find(ExtId, IntId, allocator_)) + { + // unknown section + return -2; + } + + // Handle iterator resets + if(index == 0) + { + SUBSECTION_HASH* hash_map = IntId.section_hash_map_; + if(pKey->section_iter_) + { + delete pKey->section_iter_; + } + pKey->section_iter_ = + new SUBSECTION_HASH::ITERATOR(IntId.section_hash_map_->begin()); + } + + // Get the next entry + ACE_Hash_Map_Entry<ACE_Configuration_ExtId, int>* 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 ASYS_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 + ASYS_TCHAR* pers_name = (ASYS_TCHAR*)allocator_->malloc( + (ACE_OS::strlen(name) + 1) * sizeof(ASYS_TCHAR)); + ACE_OS::strcpy(pers_name, name); + ASYS_TCHAR* pers_value = (ASYS_TCHAR*)allocator_->malloc( + (value.length() + 1) * sizeof(ASYS_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 + ASYS_TCHAR* pers_value = (ASYS_TCHAR*)allocator_->malloc( + (value.length() + 1) * sizeof(ASYS_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 ASYS_TCHAR* name, + unsigned 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_)) + { + // section does not exist + return -2; + } + + // 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 + ASYS_TCHAR* pers_name = (ASYS_TCHAR*)allocator_->malloc( + (ACE_OS::strlen(name) + 1) * sizeof(ASYS_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 ASYS_TCHAR* name, + const void* data, + unsigned 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_)) + { + // section does not exist + return -2; + } + + // 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 + ASYS_TCHAR* pers_name = (ASYS_TCHAR*)allocator_->malloc( + (ACE_OS::strlen(name) + 1) * sizeof(ASYS_TCHAR)); + ACE_OS::strcpy(pers_name, name); + ASYS_TCHAR* pers_value = (ASYS_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 + ASYS_TCHAR* pers_value = (ASYS_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 ASYS_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_)) + { + // section does not exist + return -2; + } + + // See if it exists first + ACE_Configuration_ExtId VExtId(name); + ACE_Configuration_Value_IntId VIntId; + if(IntId.value_hash_map_->find(VExtId, VIntId, allocator_)) + { + // unknown value + return -3; + } + + // Check type + if(VIntId.type_ != ACE_Configuration::STRING) + { + return -4; + } + + // everythings ok, return the data + value = (ASYS_TCHAR*)VIntId.data_; + return 0; +} + +int ACE_Configuration_Heap::get_integer_value( + const ACE_Configuration_Section_Key& key, + const ASYS_TCHAR* name, + unsigned 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_)) + { + // section does not exist + return -2; + } + + + // See if it exists first + ACE_Configuration_ExtId VExtId(name); + ACE_Configuration_Value_IntId VIntId; + if(IntId.value_hash_map_->find(VExtId, VIntId, allocator_)) + { + // unknown value + return -3; + } + + // Check type + if(VIntId.type_ != ACE_Configuration::INTEGER) + { + return -4; + } + + // Everythings ok, return the data + value = (unsigned int)VIntId.data_; + return 0; +} + +int ACE_Configuration_Heap::get_binary_value( + const ACE_Configuration_Section_Key& key, + const ASYS_TCHAR* name, + void*& data, + unsigned 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_)) + { + // section does not exist + return -2; + } + + ACE_Configuration_ExtId VExtId(name); + ACE_Configuration_Value_IntId VIntId; + // See if it exists first + if(IntId.value_hash_map_->find(VExtId, VIntId, allocator_)) + { + // unknown value + return -3; + } + + // Check type + if(VIntId.type_ != ACE_Configuration::BINARY) + { + return -4; + } + + // Make a copy + data = new char[VIntId.length_]; + 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 ASYS_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_)) + { + // section does not exist + return -2; + } + + // 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; +} |