summaryrefslogtreecommitdiff
path: root/ace/Configuration.cpp
diff options
context:
space:
mode:
authorbrunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-11-11 05:36:09 +0000
committerbrunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1999-11-11 05:36:09 +0000
commit94997be48ecf0d04ae60d9d23331876a985d7114 (patch)
tree5f5ccffb5fbc57310b9fd2af0f0b730460335b9c /ace/Configuration.cpp
parentfab28322dfcd424f569f36b2bb1312123a6f6219 (diff)
downloadATCD-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.cpp1940
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;
+}