2132 lines
60 KiB
C++
2132 lines
60 KiB
C++
|
#include "ace/Configuration.h"
|
||
|
#include "ace/Auto_Ptr.h"
|
||
|
#include "ace/SString.h"
|
||
|
#include "ace/OS_NS_string.h"
|
||
|
#include "ace/OS_NS_strings.h"
|
||
|
#include "ace/Tokenizer_T.h"
|
||
|
|
||
|
#if !defined (ACE_LACKS_ACCESS)
|
||
|
# include "ace/OS_NS_unistd.h"
|
||
|
#endif /* ACE_LACKS_ACCESS */
|
||
|
|
||
|
#if !defined (__ACE_INLINE__)
|
||
|
#include "ace/Configuration.inl"
|
||
|
#endif /* __ACE_INLINE__ */
|
||
|
|
||
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
||
|
|
||
|
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_TCHAR ACE_Configuration::NULL_String_ = '\0';
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
// Make a copy of key
|
||
|
ACE_Configuration_Section_Key current_section = key;
|
||
|
ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> pData (path_in.rep ());
|
||
|
ACE_Tokenizer parser (pData.get ());
|
||
|
parser.delimiter_replace ('\\', '\0');
|
||
|
parser.delimiter_replace ('/', '\0');
|
||
|
|
||
|
for (ACE_TCHAR *temp = parser.next ();
|
||
|
temp != 0;
|
||
|
temp = parser.next ())
|
||
|
{
|
||
|
// Open the section
|
||
|
if (open_section (current_section,
|
||
|
temp,
|
||
|
create,
|
||
|
key_out))
|
||
|
return -1;
|
||
|
|
||
|
current_section = key_out;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration::validate_name (const ACE_TCHAR* name, int allow_path)
|
||
|
{
|
||
|
// Invalid character set
|
||
|
const ACE_TCHAR* reject =
|
||
|
allow_path ? ACE_TEXT ("][") : ACE_TEXT ("\\][");
|
||
|
|
||
|
// Position of the first invalid character or terminating null.
|
||
|
size_t const pos = ACE_OS::strcspn (name, reject);
|
||
|
|
||
|
// Check if it is an invalid character.
|
||
|
if (name[pos] != ACE_TEXT ('\0'))
|
||
|
{
|
||
|
errno = EINVAL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// The first character can never be a path separator.
|
||
|
if (name[0] == ACE_TEXT ('\\'))
|
||
|
{
|
||
|
errno = EINVAL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Validate length.
|
||
|
if (pos == 0 || pos > 255)
|
||
|
{
|
||
|
errno = ENAMETOOLONG;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration::validate_value_name (const ACE_TCHAR* name)
|
||
|
{
|
||
|
if (name == 0 || *name == this->NULL_String_)
|
||
|
return 0;
|
||
|
|
||
|
return this->validate_name (name);
|
||
|
}
|
||
|
|
||
|
const ACE_Configuration_Section_Key&
|
||
|
ACE_Configuration::root_section (void) const
|
||
|
{
|
||
|
return root_;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Determine if the contents of this object is the same as the
|
||
|
* contents of the object on the right hand side.
|
||
|
* Returns 1 (True) if they are equal and 0 (False) if they are not equal
|
||
|
*/
|
||
|
bool
|
||
|
ACE_Configuration::operator== (const ACE_Configuration& rhs) const
|
||
|
{
|
||
|
bool rc = true;
|
||
|
int sectionIndex = 0;
|
||
|
ACE_TString sectionName;
|
||
|
ACE_Configuration *nonconst_this = const_cast<ACE_Configuration*> (this);
|
||
|
ACE_Configuration &nonconst_rhs = const_cast<ACE_Configuration&> (rhs);
|
||
|
|
||
|
const ACE_Configuration_Section_Key& rhsRoot = rhs.root_section ();
|
||
|
ACE_Configuration_Section_Key rhsSection;
|
||
|
ACE_Configuration_Section_Key thisSection;
|
||
|
|
||
|
// loop through each section in this object
|
||
|
while ((rc) && (nonconst_this->enumerate_sections (this->root_,
|
||
|
sectionIndex,
|
||
|
sectionName) == 0))
|
||
|
{
|
||
|
// find that section in the rhs object
|
||
|
if (nonconst_rhs.open_section (rhsRoot,
|
||
|
sectionName.c_str (),
|
||
|
0,
|
||
|
rhsSection) != 0)
|
||
|
{
|
||
|
// If the rhs object does not contain the section then we are
|
||
|
// not equal.
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (nonconst_this->open_section (this->root_,
|
||
|
sectionName.c_str (),
|
||
|
0,
|
||
|
thisSection) != 0)
|
||
|
{
|
||
|
// if there is some error opening the section in this object
|
||
|
rc = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Well the sections match
|
||
|
int valueIndex = 0;
|
||
|
ACE_TString valueName;
|
||
|
VALUETYPE valueType;
|
||
|
VALUETYPE rhsType;
|
||
|
|
||
|
// Enumerate each value in this section
|
||
|
while ((rc) && nonconst_this->enumerate_values (thisSection,
|
||
|
valueIndex,
|
||
|
valueName,
|
||
|
valueType) == 0)
|
||
|
{
|
||
|
// look for the same value in the rhs section
|
||
|
if (nonconst_rhs.find_value (rhsSection,
|
||
|
valueName.c_str (),
|
||
|
rhsType) != 0)
|
||
|
{
|
||
|
// We're not equal if the same value cannot
|
||
|
// be found in the rhs object.
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (valueType != rhsType)
|
||
|
{
|
||
|
// we're not equal if the types do not match.
|
||
|
rc = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// finally compare values.
|
||
|
if (valueType == STRING)
|
||
|
{
|
||
|
ACE_TString thisString, rhsString;
|
||
|
if (nonconst_this->get_string_value (thisSection,
|
||
|
valueName.c_str (),
|
||
|
thisString) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get this string
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (nonconst_rhs.get_string_value (
|
||
|
rhsSection,
|
||
|
valueName.c_str (),
|
||
|
rhsString) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get rhs string
|
||
|
rc = false;
|
||
|
}
|
||
|
rc = (thisString == rhsString);
|
||
|
}
|
||
|
else if (valueType == INTEGER)
|
||
|
{
|
||
|
u_int thisInt = 0;
|
||
|
u_int rhsInt = 0;
|
||
|
if (nonconst_this->get_integer_value (
|
||
|
thisSection,
|
||
|
valueName.c_str (),
|
||
|
thisInt) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get this int
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (nonconst_rhs.get_integer_value (
|
||
|
rhsSection,
|
||
|
valueName.c_str (),
|
||
|
rhsInt) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get rhs int
|
||
|
rc = false;
|
||
|
}
|
||
|
rc = (thisInt == rhsInt);
|
||
|
}
|
||
|
else if (valueType == BINARY)
|
||
|
{
|
||
|
void* thisData = 0;
|
||
|
void* rhsData = 0;
|
||
|
size_t thisLength = 0;
|
||
|
size_t rhsLength = 0;
|
||
|
if (nonconst_this->get_binary_value (thisSection,
|
||
|
valueName.c_str (),
|
||
|
thisData,
|
||
|
thisLength) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get this data
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (nonconst_rhs.get_binary_value (
|
||
|
rhsSection,
|
||
|
valueName.c_str (),
|
||
|
rhsData,
|
||
|
rhsLength) != 0)
|
||
|
{
|
||
|
// we're not equal if we cannot get this data
|
||
|
rc = false;
|
||
|
}
|
||
|
|
||
|
rc = (thisLength == rhsLength);
|
||
|
// are the length's the same?
|
||
|
|
||
|
if (rc)
|
||
|
{
|
||
|
unsigned char* thisCharData =
|
||
|
(unsigned char*)thisData;
|
||
|
unsigned char* rhsCharData = (unsigned char*)rhsData;
|
||
|
// yes, then check each element
|
||
|
for (size_t count = 0;
|
||
|
(rc) && (count < thisLength);
|
||
|
count++)
|
||
|
{
|
||
|
rc = (* (thisCharData + count) == * (rhsCharData + count));
|
||
|
}
|
||
|
|
||
|
delete [] thisCharData;
|
||
|
delete [] rhsCharData;
|
||
|
}// end if the length's match
|
||
|
}
|
||
|
// We should never have valueTypes of INVALID, therefore
|
||
|
// we're not comparing them. How would we since we have
|
||
|
// no get operation for invalid types.
|
||
|
// So, if we have them, we guess they are equal.
|
||
|
|
||
|
}// end else if values match.
|
||
|
|
||
|
++valueIndex;
|
||
|
|
||
|
}// end value while loop
|
||
|
|
||
|
// look in the rhs for values not in this
|
||
|
valueIndex = 0;
|
||
|
while ((rc) && (nonconst_rhs.enumerate_values (rhsSection,
|
||
|
valueIndex,
|
||
|
valueName,
|
||
|
rhsType) == 0))
|
||
|
{
|
||
|
// look for the same value in this section
|
||
|
if (nonconst_this->find_value (thisSection,
|
||
|
valueName.c_str (),
|
||
|
valueType) != 0)
|
||
|
{
|
||
|
// We're not equal if the same value cannot
|
||
|
// be found in the rhs object.
|
||
|
rc = false;
|
||
|
}
|
||
|
++valueIndex;
|
||
|
}// end while for rhs values not in this.
|
||
|
|
||
|
}// end else if sections match.
|
||
|
|
||
|
++sectionIndex;
|
||
|
|
||
|
}// end section while loop
|
||
|
|
||
|
// Finally, make sure that there are no sections in rhs that do not
|
||
|
// exist in this
|
||
|
sectionIndex = 0;
|
||
|
while ((rc)
|
||
|
&& (nonconst_rhs.enumerate_sections (rhsRoot,
|
||
|
sectionIndex,
|
||
|
sectionName) == 0))
|
||
|
{
|
||
|
// find the section in this
|
||
|
if (nonconst_this->open_section (this->root_,
|
||
|
sectionName.c_str (),
|
||
|
0,
|
||
|
thisSection) != 0)
|
||
|
{
|
||
|
// if there is some error opening the section in this object
|
||
|
rc = false;
|
||
|
}
|
||
|
else if (nonconst_rhs.open_section (rhsRoot,
|
||
|
sectionName.c_str (),
|
||
|
0,
|
||
|
rhsSection) != 0)
|
||
|
{
|
||
|
// If the rhs object does not contain the section then we
|
||
|
// are not equal.
|
||
|
rc = false;
|
||
|
}
|
||
|
++sectionIndex;
|
||
|
}
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
ACE_Configuration::operator!= (const ACE_Configuration& rhs) const
|
||
|
{
|
||
|
return !(*this == rhs);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
|
||
|
|
||
|
static const int ACE_DEFAULT_BUFSIZE = 256;
|
||
|
|
||
|
static const ACE_TCHAR *temp_name (const ACE_TCHAR *name)
|
||
|
{
|
||
|
if (name && *name == ACE_Configuration::NULL_String_)
|
||
|
return 0;
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
ACE_Section_Key_Win32::ACE_Section_Key_Win32 (HKEY hKey)
|
||
|
: hKey_ (hKey)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ACE_Section_Key_Win32::~ACE_Section_Key_Win32 (void)
|
||
|
{
|
||
|
::RegCloseKey (hKey_);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
bool
|
||
|
ACE_Configuration_Win32Registry::operator== (const ACE_Configuration_Win32Registry &rhs) const
|
||
|
{
|
||
|
ACE_UNUSED_ARG (rhs);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
ACE_Configuration_Win32Registry::operator!= (const ACE_Configuration_Win32Registry &rhs) const
|
||
|
{
|
||
|
ACE_UNUSED_ARG (rhs);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry (HKEY hKey)
|
||
|
{
|
||
|
ACE_Section_Key_Win32 *temp = 0;
|
||
|
|
||
|
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 ACE_TCHAR* sub_section,
|
||
|
int create,
|
||
|
ACE_Configuration_Section_Key& result)
|
||
|
{
|
||
|
if (validate_name (sub_section, 1))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (base, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
HKEY result_key;
|
||
|
if ((errnum = ACE_TEXT_RegOpenKeyEx (base_key,
|
||
|
sub_section,
|
||
|
0,
|
||
|
KEY_ALL_ACCESS,
|
||
|
&result_key)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
if (!create)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if ((errnum = ACE_TEXT_RegCreateKeyEx (base_key,
|
||
|
sub_section,
|
||
|
0,
|
||
|
0,
|
||
|
REG_OPTION_NON_VOLATILE,
|
||
|
KEY_ALL_ACCESS,
|
||
|
0,
|
||
|
&result_key,
|
||
|
(PDWORD) 0
|
||
|
)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ACE_Section_Key_Win32 *temp;
|
||
|
|
||
|
ACE_NEW_RETURN (temp, ACE_Section_Key_Win32 (result_key), -1);
|
||
|
result = ACE_Configuration_Section_Key (temp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::remove_section (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* sub_section,
|
||
|
bool 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 -1;
|
||
|
|
||
|
HKEY sub_key;
|
||
|
if (load_key (section, sub_key))
|
||
|
return -1;
|
||
|
|
||
|
ACE_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 (ACE_TEXT_RegEnumKeyEx (sub_key,
|
||
|
0,
|
||
|
name_buffer,
|
||
|
&buffer_size,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0) == ERROR_SUCCESS)
|
||
|
{
|
||
|
remove_section (section, name_buffer, true);
|
||
|
buffer_size = ACE_DEFAULT_BUFSIZE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int const errnum = ACE_TEXT_RegDeleteKey (base_key, sub_section);
|
||
|
if (errnum != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
|
||
|
ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
|
||
|
DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
|
||
|
DWORD value_type;
|
||
|
|
||
|
int rc = ACE_TEXT_RegEnumValue (base_key,
|
||
|
index,
|
||
|
name_buffer,
|
||
|
&buffer_size,
|
||
|
0,
|
||
|
&value_type,
|
||
|
0,
|
||
|
0);
|
||
|
if (rc == ERROR_NO_MORE_ITEMS)
|
||
|
return 1;
|
||
|
else if (rc != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = rc;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
|
||
|
ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
|
||
|
DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
|
||
|
int rc = ACE_TEXT_RegEnumKeyEx (base_key,
|
||
|
index,
|
||
|
name_buffer,
|
||
|
&buffer_size,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
0);
|
||
|
if (rc == ERROR_NO_MORE_ITEMS)
|
||
|
return 1;
|
||
|
else if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = rc;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
name = name_buffer;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::set_string_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
const ACE_TString& value)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
DWORD len = static_cast<DWORD> (value.length () + 1);
|
||
|
len *= sizeof (ACE_TCHAR);
|
||
|
if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
REG_SZ,
|
||
|
(BYTE *) value.fast_rep (),
|
||
|
len))
|
||
|
!= ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::set_integer_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
u_int value)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
REG_DWORD,
|
||
|
(BYTE *) &value,
|
||
|
sizeof (value))) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::set_binary_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
const void* data,
|
||
|
size_t length)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
REG_BINARY,
|
||
|
(BYTE *) data,
|
||
|
static_cast<DWORD> (length)))
|
||
|
!= ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::get_string_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
ACE_TString& value)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
// Get the size of the binary data from windows
|
||
|
int errnum;
|
||
|
DWORD buffer_length = 0;
|
||
|
DWORD type;
|
||
|
if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
(BYTE *) 0,
|
||
|
&buffer_length)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (type != REG_SZ)
|
||
|
{
|
||
|
errno = ERROR_INVALID_DATATYPE;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ACE_TCHAR *temp = 0;
|
||
|
ACE_NEW_RETURN (temp,
|
||
|
ACE_TCHAR[buffer_length],
|
||
|
-1);
|
||
|
|
||
|
ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> buffer (temp);
|
||
|
|
||
|
if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
(BYTE *) buffer.get (),
|
||
|
&buffer_length)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
value = buffer.get ();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::get_integer_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
u_int& value)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
DWORD length = sizeof (value);
|
||
|
DWORD type;
|
||
|
if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
(BYTE *) &value,
|
||
|
&length)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (type != REG_DWORD)
|
||
|
{
|
||
|
errno = ERROR_INVALID_DATATYPE;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::get_binary_value (
|
||
|
const ACE_Configuration_Section_Key &key,
|
||
|
const ACE_TCHAR *name,
|
||
|
void *&data,
|
||
|
size_t &length)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
// Get the size of the binary data from windows
|
||
|
int errnum;
|
||
|
DWORD buffer_length = 0;
|
||
|
DWORD type;
|
||
|
if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
(BYTE *) 0,
|
||
|
&buffer_length)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (type != REG_BINARY)
|
||
|
{
|
||
|
errno = ERROR_INVALID_DATATYPE;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
length = buffer_length;
|
||
|
|
||
|
BYTE * the_data = 0;
|
||
|
ACE_NEW_RETURN (the_data, BYTE[length], -1);
|
||
|
ACE_Auto_Basic_Array_Ptr<BYTE> safe_data (the_data);
|
||
|
|
||
|
if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
the_data,
|
||
|
&buffer_length)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
data = 0;
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
data = safe_data.release ();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::find_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
VALUETYPE& type_out)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
DWORD buffer_length=0;
|
||
|
DWORD type;
|
||
|
int result=ACE_TEXT_RegQueryValueEx (base_key,
|
||
|
t_name,
|
||
|
0,
|
||
|
&type,
|
||
|
0,
|
||
|
&buffer_length);
|
||
|
if (result != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = result;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
case REG_SZ:
|
||
|
type_out = STRING;
|
||
|
break;
|
||
|
case REG_DWORD:
|
||
|
type_out = INTEGER;
|
||
|
break;
|
||
|
case REG_BINARY:
|
||
|
type_out = BINARY;
|
||
|
break;
|
||
|
default:
|
||
|
return -1; // unknown type
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::remove_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name)
|
||
|
{
|
||
|
const ACE_TCHAR *t_name = temp_name (name);
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
HKEY base_key;
|
||
|
if (load_key (key, base_key))
|
||
|
return -1;
|
||
|
|
||
|
int errnum;
|
||
|
if ((errnum = ACE_TEXT_RegDeleteValue (base_key, t_name)) != ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Win32Registry::load_key (const ACE_Configuration_Section_Key& key,
|
||
|
HKEY& hKey)
|
||
|
{
|
||
|
ACE_Section_Key_Win32* pKey = 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 ACE_TCHAR* path,
|
||
|
int create)
|
||
|
{
|
||
|
HKEY result = 0;
|
||
|
// Make a copy of hKey
|
||
|
int errnum;
|
||
|
#if defined (ACE_HAS_WINCE)
|
||
|
if ((errnum = RegOpenKeyEx (hKey, 0, 0, 0, &result)) != ERROR_SUCCESS)
|
||
|
#else
|
||
|
if ((errnum = RegOpenKey (hKey, 0, &result)) != ERROR_SUCCESS)
|
||
|
#endif // ACE_HAS_WINCE
|
||
|
{
|
||
|
errno = errnum;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// recurse through the path
|
||
|
ACE_TCHAR *temp_path = 0;
|
||
|
ACE_NEW_RETURN (temp_path,
|
||
|
ACE_TCHAR[ACE_OS::strlen (path) + 1],
|
||
|
0);
|
||
|
ACE_Auto_Basic_Array_Ptr<ACE_TCHAR> pData (temp_path);
|
||
|
ACE_OS::strcpy (pData.get (), path);
|
||
|
ACE_Tokenizer parser (pData.get ());
|
||
|
parser.delimiter_replace ('\\', '\0');
|
||
|
parser.delimiter_replace ('/', '\0');
|
||
|
|
||
|
for (ACE_TCHAR *temp = parser.next ();
|
||
|
temp != 0;
|
||
|
temp = parser.next ())
|
||
|
{
|
||
|
// Open the key
|
||
|
HKEY subkey;
|
||
|
|
||
|
#if defined (ACE_HAS_WINCE)
|
||
|
if ((errnum = ACE_TEXT_RegOpenKeyEx (result,
|
||
|
temp,
|
||
|
0,
|
||
|
0,
|
||
|
&subkey)) != ERROR_SUCCESS)
|
||
|
#else
|
||
|
if ((errnum = ACE_TEXT_RegOpenKey (result,
|
||
|
temp,
|
||
|
&subkey)) != ERROR_SUCCESS)
|
||
|
#endif // ACE_HAS_WINCE
|
||
|
{
|
||
|
// try creating it
|
||
|
if (!create || (errnum = ACE_TEXT_RegCreateKeyEx (result,
|
||
|
temp,
|
||
|
0,
|
||
|
0,
|
||
|
0,
|
||
|
KEY_ALL_ACCESS,
|
||
|
0,
|
||
|
&subkey,
|
||
|
(PDWORD) 0
|
||
|
)) !=ERROR_SUCCESS)
|
||
|
{
|
||
|
errno = errnum;
|
||
|
// error
|
||
|
::RegCloseKey (result);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
// release our open key handle
|
||
|
::RegCloseKey (result);
|
||
|
result = subkey;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */
|
||
|
|
||
|
///////////////////////////////////////////////////////////////
|
||
|
|
||
|
ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void)
|
||
|
: type_ (ACE_Configuration::INVALID),
|
||
|
length_ (0)
|
||
|
{
|
||
|
this->data_.ptr_ = 0;
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (ACE_TCHAR* string)
|
||
|
: type_ (ACE_Configuration::STRING),
|
||
|
length_ (0)
|
||
|
{
|
||
|
this->data_.ptr_ = string;
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (u_int integer)
|
||
|
: type_ (ACE_Configuration::INTEGER),
|
||
|
length_ (0)
|
||
|
{
|
||
|
this->data_.int_ = integer;
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void* data, size_t length)
|
||
|
: type_ (ACE_Configuration::BINARY),
|
||
|
length_ (length)
|
||
|
{
|
||
|
this->data_.ptr_ = data;
|
||
|
}
|
||
|
|
||
|
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 *alloc)
|
||
|
{
|
||
|
if (this->type_ == ACE_Configuration::STRING
|
||
|
|| this->type_ == ACE_Configuration::BINARY)
|
||
|
alloc->free (data_.ptr_);
|
||
|
// Do nothing in other cases...
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_ExtId::ACE_Configuration_ExtId (void)
|
||
|
: name_ (0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_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;
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
ACE_Configuration_ExtId::operator== (const ACE_Configuration_ExtId& rhs) const
|
||
|
{
|
||
|
return (ACE_OS::strcasecmp (name_, rhs.name_) == 0);
|
||
|
}
|
||
|
|
||
|
bool
|
||
|
ACE_Configuration_ExtId::operator!= (const ACE_Configuration_ExtId& rhs) const
|
||
|
{
|
||
|
return !this->operator== (rhs);
|
||
|
}
|
||
|
|
||
|
u_long
|
||
|
ACE_Configuration_ExtId::hash (void) const
|
||
|
{
|
||
|
ACE_TString temp (name_, 0, false);
|
||
|
return temp.hash ();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
ACE_Configuration_ExtId::free (ACE_Allocator *alloc)
|
||
|
{
|
||
|
alloc->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 *alloc)
|
||
|
{
|
||
|
alloc->free ((void *) (value_hash_map_));
|
||
|
alloc->free ((void *) (section_hash_map_));
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Section_Key_Heap::ACE_Configuration_Section_Key_Heap (const ACE_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 (size_t default_map_size)
|
||
|
{
|
||
|
if (this->allocator_ != 0)
|
||
|
{
|
||
|
errno = EBUSY;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
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 ACE_TCHAR* file_name,
|
||
|
void* base_address,
|
||
|
size_t default_map_size)
|
||
|
{
|
||
|
if (this->allocator_ != 0)
|
||
|
{
|
||
|
errno = EBUSY;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
ACE_MMAP_Memory_Pool::OPTIONS options (base_address);
|
||
|
|
||
|
// 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)
|
||
|
ACELIB_ERROR_RETURN ((LM_ERROR,
|
||
|
ACE_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 <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.
|
||
|
ACELIB_ERROR ((LM_ERROR,
|
||
|
ACE_TEXT ("create_index failed\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_ASSERT (this->allocator_);
|
||
|
this->index_ = new (buffer) SECTION_MAP (this->allocator_);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::load_key (const ACE_Configuration_Section_Key& key,
|
||
|
ACE_TString& name)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
ACE_Configuration_Section_Key_Heap* pKey =
|
||
|
dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
|
||
|
|
||
|
if (!pKey)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ACE_TString temp (pKey->path_, 0, false);
|
||
|
name.assign_nocopy (temp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::add_section (const ACE_Configuration_Section_Key& base,
|
||
|
const ACE_TCHAR* sub_section,
|
||
|
ACE_Configuration_Section_Key& result)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
ACE_TString section;
|
||
|
if (load_key (base, section))
|
||
|
return -1;
|
||
|
|
||
|
// Find the base section
|
||
|
ACE_Configuration_ExtId ExtId (section.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
return -1;
|
||
|
|
||
|
// 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!
|
||
|
errno = EEXIST;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Create the new section name
|
||
|
// only prepend a separater if were not at the root
|
||
|
if (section.length ())
|
||
|
section += ACE_TEXT ("\\");
|
||
|
|
||
|
section += sub_section;
|
||
|
|
||
|
// Add it to the base section
|
||
|
ACE_TCHAR* pers_name = (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (sub_section) + 1) * sizeof (ACE_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 -1;
|
||
|
}
|
||
|
return (new_section (section, result));
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::new_section (const ACE_TString& section,
|
||
|
ACE_Configuration_Section_Key& result)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
// 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;
|
||
|
ACE_TCHAR *ptr = (ACE_TCHAR*) this->allocator_->malloc (section_len * sizeof (ACE_TCHAR));
|
||
|
|
||
|
int return_value = -1;
|
||
|
|
||
|
if (ptr == 0)
|
||
|
return -1;
|
||
|
else
|
||
|
{
|
||
|
// Populate memory with data.
|
||
|
ACE_OS::strcpy (ptr, section.fast_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 -1;
|
||
|
}
|
||
|
|
||
|
// 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 -1;
|
||
|
}
|
||
|
|
||
|
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. */
|
||
|
|| return_value == -1 /* Unable to bind for other reasons. */)
|
||
|
{
|
||
|
// Free our dynamically allocated memory.
|
||
|
this->allocator_->free (static_cast<void *> (ptr));
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
// 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 (ptr),
|
||
|
-1);
|
||
|
result = ACE_Configuration_Section_Key (temp);
|
||
|
return return_value;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::value_open_helper (size_t hash_table_size,
|
||
|
void *buffer)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
new (buffer) VALUE_MAP (hash_table_size, this->allocator_);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::section_open_helper (size_t hash_table_size,
|
||
|
void *buffer)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
new (buffer) SUBSECTION_MAP (hash_table_size, this->allocator_);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::open_section (const ACE_Configuration_Section_Key& base,
|
||
|
const ACE_TCHAR* sub_section,
|
||
|
int create,
|
||
|
ACE_Configuration_Section_Key& result)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
if (validate_name (sub_section, 1)) // 1 == allow_path
|
||
|
return -1;
|
||
|
|
||
|
result = base;
|
||
|
|
||
|
for (const ACE_TCHAR* separator;
|
||
|
(separator = ACE_OS::strchr (sub_section, ACE_TEXT ('\\'))) != 0;
|
||
|
)
|
||
|
{
|
||
|
ACE_TString simple_section (sub_section, separator - sub_section);
|
||
|
int ret_val =
|
||
|
open_simple_section (result, simple_section.c_str (), create, result);
|
||
|
if (ret_val)
|
||
|
return ret_val;
|
||
|
sub_section = separator + 1;
|
||
|
}
|
||
|
|
||
|
return open_simple_section (result, sub_section, create, result);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::open_simple_section (const ACE_Configuration_Section_Key& base,
|
||
|
const ACE_TCHAR* sub_section,
|
||
|
int create,
|
||
|
ACE_Configuration_Section_Key& result)
|
||
|
{
|
||
|
ACE_TString section (0, 0, false);
|
||
|
|
||
|
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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
{
|
||
|
if (!create)
|
||
|
{
|
||
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return add_section (base, sub_section, result);
|
||
|
}
|
||
|
|
||
|
ACE_Configuration_Section_Key_Heap *temp;
|
||
|
ACE_NEW_RETURN (temp,
|
||
|
ACE_Configuration_Section_Key_Heap (section.fast_rep ()),
|
||
|
-1);
|
||
|
result = ACE_Configuration_Section_Key (temp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::remove_section (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* sub_section,
|
||
|
bool recursive)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId ParentIntId;
|
||
|
if (index_->find (ParentExtId, ParentIntId, allocator_))
|
||
|
return -1;// no parent key
|
||
|
|
||
|
// Find this subkey
|
||
|
if (section.length ())
|
||
|
section += ACE_TEXT ("\\");
|
||
|
|
||
|
section += sub_section;
|
||
|
ACE_Configuration_ExtId SectionExtId (section.fast_rep ());
|
||
|
SECTION_HASH::ENTRY* section_entry = 0;
|
||
|
SECTION_HASH* hashmap = index_;
|
||
|
if (hashmap->find (SectionExtId, section_entry))
|
||
|
return -1;
|
||
|
|
||
|
if (recursive)
|
||
|
{
|
||
|
ACE_Configuration_Section_Key recursive_section;
|
||
|
if (open_section (key, sub_section, 0, recursive_section))
|
||
|
return -1;
|
||
|
|
||
|
int index = 0;
|
||
|
ACE_TString name;
|
||
|
while (!enumerate_sections (recursive_section, index, name))
|
||
|
{
|
||
|
if (remove_section (recursive_section, name.fast_rep (), true))
|
||
|
return -1;
|
||
|
|
||
|
++index;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now make sure we dont have any subkeys
|
||
|
if (section_entry->int_id_.section_hash_map_->current_size ())
|
||
|
{
|
||
|
errno = ENOTEMPTY;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Now remove subkey from parent key
|
||
|
ACE_Configuration_ExtId SubSExtId (sub_section);
|
||
|
SUBSECTION_HASH::ENTRY* subsection_entry = 0;
|
||
|
if (((SUBSECTION_HASH*)ParentIntId.section_hash_map_)->
|
||
|
find (SubSExtId, subsection_entry))
|
||
|
return -1;
|
||
|
|
||
|
if (ParentIntId.section_hash_map_->unbind (SubSExtId, allocator_))
|
||
|
return -1;
|
||
|
|
||
|
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_HASH::ENTRY* value_entry = 0;
|
||
|
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 -1;
|
||
|
|
||
|
value_hash_map->close ();
|
||
|
section_entry->int_id_.section_hash_map_->close (allocator_);
|
||
|
|
||
|
// 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_ASSERT (this->allocator_);
|
||
|
ACE_Configuration_Section_Key_Heap* pKey =
|
||
|
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 -1;
|
||
|
|
||
|
// 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_;
|
||
|
delete pKey->value_iter_;
|
||
|
|
||
|
ACE_NEW_RETURN (pKey->value_iter_,
|
||
|
VALUE_HASH::ITERATOR (hash_map->begin ()),
|
||
|
-1);
|
||
|
}
|
||
|
|
||
|
// Get the next entry
|
||
|
ACE_Hash_Map_Entry<ACE_Configuration_ExtId, ACE_Configuration_Value_IntId>* entry = 0;
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
// cast to a heap section key
|
||
|
ACE_Configuration_Section_Key_Heap* pKey =
|
||
|
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 -1; // 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 ()),
|
||
|
-1);
|
||
|
}
|
||
|
|
||
|
// Get the next entry
|
||
|
ACE_Hash_Map_Entry<ACE_Configuration_ExtId, int>* entry = 0;
|
||
|
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 ACE_TCHAR* name,
|
||
|
const ACE_TString& value)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
ACE_TString section;
|
||
|
if (load_key (key, section))
|
||
|
return -1;
|
||
|
|
||
|
ACE_Configuration_ExtId section_ext (section.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId section_int;
|
||
|
if (index_->find (section_ext, section_int, allocator_))
|
||
|
return -1;
|
||
|
|
||
|
// Get the entry for this item (if it exists)
|
||
|
VALUE_HASH::ENTRY* entry = 0;
|
||
|
ACE_Configuration_ExtId item_name (t_name);
|
||
|
if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
|
||
|
{
|
||
|
// found item, replace it
|
||
|
// Free the old value
|
||
|
entry->int_id_.free (allocator_);
|
||
|
// Allocate the new value in this heap
|
||
|
ACE_TCHAR* pers_value =
|
||
|
(ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
|
||
|
ACE_OS::strcpy (pers_value, value.fast_rep ());
|
||
|
ACE_Configuration_Value_IntId new_value_int (pers_value);
|
||
|
entry->int_id_ = new_value_int;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// it doesn't exist, bind it
|
||
|
ACE_TCHAR* pers_name =
|
||
|
(ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
|
||
|
ACE_OS::strcpy (pers_name, t_name);
|
||
|
ACE_TCHAR* pers_value =
|
||
|
(ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
|
||
|
ACE_OS::strcpy (pers_value, value.fast_rep ());
|
||
|
ACE_Configuration_ExtId new_item_name (pers_name);
|
||
|
ACE_Configuration_Value_IntId item_value (pers_value);
|
||
|
if (section_int.value_hash_map_->bind (new_item_name, item_value, allocator_))
|
||
|
{
|
||
|
allocator_->free (pers_value);
|
||
|
allocator_->free (pers_name);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::set_integer_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
u_int value)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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 section_ext (section.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId section_int;
|
||
|
if (index_->find (section_ext, section_int, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
// Get the entry for this item (if it exists)
|
||
|
VALUE_HASH::ENTRY* entry = 0;
|
||
|
ACE_Configuration_ExtId item_name (t_name);
|
||
|
if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
|
||
|
{
|
||
|
// found item, replace it
|
||
|
ACE_Configuration_Value_IntId new_value_int (value);
|
||
|
entry->int_id_ = new_value_int;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// it doesn't exist, bind it
|
||
|
ACE_TCHAR* pers_name =
|
||
|
(ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
|
||
|
ACE_OS::strcpy (pers_name, t_name);
|
||
|
ACE_Configuration_ExtId item_name (pers_name);
|
||
|
ACE_Configuration_Value_IntId item_value (value);
|
||
|
if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
|
||
|
{
|
||
|
allocator_->free (pers_name);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::set_binary_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
const void* data,
|
||
|
size_t length)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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 section_ext (section.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId section_int;
|
||
|
if (index_->find (section_ext, section_int, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
// Get the entry for this item (if it exists)
|
||
|
VALUE_HASH::ENTRY* entry = 0;
|
||
|
ACE_Configuration_ExtId item_name (t_name);
|
||
|
if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
|
||
|
{
|
||
|
// found item, replace it
|
||
|
// Free the old value
|
||
|
entry->int_id_.free (allocator_);
|
||
|
// Allocate the new value in this heap
|
||
|
ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
|
||
|
ACE_OS::memcpy (pers_value, data, length);
|
||
|
ACE_Configuration_Value_IntId new_value_int (pers_value, length);
|
||
|
entry->int_id_ = new_value_int;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// it doesn't exist, bind it
|
||
|
ACE_TCHAR* pers_name =
|
||
|
(ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
|
||
|
ACE_OS::strcpy (pers_name, t_name);
|
||
|
ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
|
||
|
ACE_OS::memcpy (pers_value, data, length);
|
||
|
ACE_Configuration_ExtId item_name (pers_name);
|
||
|
ACE_Configuration_Value_IntId item_value (pers_value, length);
|
||
|
if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
|
||
|
{
|
||
|
allocator_->free (pers_value);
|
||
|
allocator_->free (pers_name);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::get_string_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
ACE_TString& value)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
// See if it exists first
|
||
|
ACE_Configuration_ExtId VExtId (t_name);
|
||
|
ACE_Configuration_Value_IntId VIntId;
|
||
|
if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
|
||
|
return -1; // unknown value
|
||
|
|
||
|
// Check type
|
||
|
if (VIntId.type_ != ACE_Configuration::STRING)
|
||
|
{
|
||
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// everythings ok, return the data
|
||
|
value = static_cast<ACE_TCHAR*> (VIntId.data_.ptr_);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::get_integer_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
u_int& value)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_name))
|
||
|
return -1;
|
||
|
|
||
|
// Get the section name from the key
|
||
|
ACE_TString section (0, 0, false);
|
||
|
|
||
|
if (this->load_key (key, section) != 0)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Find this section
|
||
|
ACE_Configuration_ExtId ExtId (section.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
|
||
|
if (index_->find (ExtId, IntId, allocator_) != 0)
|
||
|
{
|
||
|
return -1; // section does not exist
|
||
|
}
|
||
|
|
||
|
|
||
|
// See if it exists first
|
||
|
ACE_Configuration_ExtId VExtId (t_name);
|
||
|
ACE_Configuration_Value_IntId VIntId;
|
||
|
|
||
|
if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_) != 0)
|
||
|
{
|
||
|
return -1; // unknown value
|
||
|
}
|
||
|
|
||
|
// Check type
|
||
|
if (VIntId.type_ != ACE_Configuration::INTEGER)
|
||
|
{
|
||
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Everythings ok, return the data
|
||
|
value = VIntId.data_.int_;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::get_binary_value (
|
||
|
const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
void*& data,
|
||
|
size_t& length)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
ACE_Configuration_ExtId VExtId (t_name);
|
||
|
ACE_Configuration_Value_IntId VIntId;
|
||
|
// See if it exists first
|
||
|
if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
|
||
|
return -1; // unknown value
|
||
|
|
||
|
// Check type
|
||
|
if (VIntId.type_ != ACE_Configuration::BINARY)
|
||
|
{
|
||
|
errno = ENOENT;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Make a copy
|
||
|
ACE_NEW_RETURN (data, char[VIntId.length_], -1);
|
||
|
ACE_OS::memcpy (data, VIntId.data_.ptr_, VIntId.length_);
|
||
|
length = VIntId.length_;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::find_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name,
|
||
|
VALUETYPE& type_out)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
// Find it
|
||
|
ACE_Configuration_ExtId ValueExtId (t_name);
|
||
|
VALUE_HASH::ENTRY* value_entry = 0;
|
||
|
if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
|
||
|
return -1; // value does not exist
|
||
|
|
||
|
type_out = value_entry->int_id_.type_;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
ACE_Configuration_Heap::remove_value (const ACE_Configuration_Section_Key& key,
|
||
|
const ACE_TCHAR* name)
|
||
|
{
|
||
|
ACE_ASSERT (this->allocator_);
|
||
|
const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
|
||
|
if (validate_value_name (t_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.fast_rep ());
|
||
|
ACE_Configuration_Section_IntId IntId;
|
||
|
if (index_->find (ExtId, IntId, allocator_))
|
||
|
return -1; // section does not exist
|
||
|
|
||
|
// Find it
|
||
|
ACE_Configuration_ExtId ValueExtId (t_name);
|
||
|
VALUE_HASH::ENTRY* value_entry = 0;
|
||
|
if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
|
||
|
return -1;
|
||
|
|
||
|
// 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 -1;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
ACE_END_VERSIONED_NAMESPACE_DECL
|