Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Configuration.cpp
bloba902e263c4a2d9efff6a2e9c24f02f83ea787df9
1 #include "ace/Configuration.h"
2 #include "ace/SString.h"
3 #include "ace/OS_NS_string.h"
4 #include "ace/OS_NS_strings.h"
5 #include "ace/Tokenizer_T.h"
7 #if !defined (ACE_LACKS_ACCESS)
8 # include "ace/OS_NS_unistd.h"
9 #endif /* ACE_LACKS_ACCESS */
11 #if !defined (__ACE_INLINE__)
12 #include "ace/Configuration.inl"
13 #endif /* __ACE_INLINE__ */
15 #if defined (ACE_HAS_ALLOC_HOOKS)
16 # include "ace/Malloc_Base.h"
17 #endif /* ACE_HAS_ALLOC_HOOKS */
19 #include <memory>
21 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
23 int
24 ACE_Section_Key_Internal::add_ref ()
26 ++ref_count_;
27 return 0;
30 int
31 ACE_Section_Key_Internal::dec_ref ()
33 if (!--ref_count_)
34 delete this;
35 return 0;
38 ACE_Configuration_Section_Key::~ACE_Configuration_Section_Key ()
40 if (key_)
41 key_->dec_ref ();
44 ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (ACE_Section_Key_Internal* key)
45 : key_ (key)
47 if (key_)
48 key_->add_ref ();
51 ACE_Configuration_Section_Key::ACE_Configuration_Section_Key (const ACE_Configuration_Section_Key& rhs)
52 : key_ (rhs.key_)
54 if (key_)
55 key_->add_ref ();
58 ACE_Configuration_Section_Key&
59 ACE_Configuration_Section_Key::operator= (const ACE_Configuration_Section_Key& rhs)
61 if (this != &rhs)
63 if (key_)
64 key_->dec_ref ();
66 key_ = rhs.key_;
68 if (key_)
69 key_->add_ref ();
71 return *this;
74 //////////////////////////////////////////////////////////////////////////////
76 ACE_TCHAR ACE_Configuration::NULL_String_ = '\0';
78 ACE_Configuration::ACE_Configuration ()
79 : root_ ()
83 ACE_Section_Key_Internal*
84 ACE_Configuration::get_internal_key (const ACE_Configuration_Section_Key& key)
86 return key.key_;
89 int
90 ACE_Configuration::expand_path (const ACE_Configuration_Section_Key& key,
91 const ACE_TString& path_in,
92 ACE_Configuration_Section_Key& key_out,
93 bool create)
95 // Make a copy of key
96 ACE_Configuration_Section_Key current_section = key;
97 std::unique_ptr<ACE_TCHAR[]> pData (path_in.rep ());
98 ACE_Tokenizer parser (pData.get ());
99 parser.delimiter_replace ('\\', '\0');
100 parser.delimiter_replace ('/', '\0');
102 for (ACE_TCHAR *temp = parser.next ();
103 temp != 0;
104 temp = parser.next ())
106 // Open the section
107 if (open_section (current_section,
108 temp,
109 create,
110 key_out))
111 return -1;
113 current_section = key_out;
116 return 0;
120 ACE_Configuration::validate_name (const ACE_TCHAR* name, int allow_path)
122 // Invalid character set
123 const ACE_TCHAR* reject =
124 allow_path ? ACE_TEXT ("][") : ACE_TEXT ("\\][");
126 // Position of the first invalid character or terminating null.
127 size_t const pos = ACE_OS::strcspn (name, reject);
129 // Check if it is an invalid character.
130 if (name[pos] != ACE_TEXT ('\0'))
132 errno = EINVAL;
133 return -1;
136 // The first character can never be a path separator.
137 if (name[0] == ACE_TEXT ('\\'))
139 errno = EINVAL;
140 return -1;
143 // Validate length.
144 if (pos == 0 || pos > 255)
146 errno = ENAMETOOLONG;
147 return -1;
150 return 0;
154 ACE_Configuration::validate_value_name (const ACE_TCHAR* name)
156 if (name == 0 || *name == this->NULL_String_)
157 return 0;
159 return this->validate_name (name);
162 const ACE_Configuration_Section_Key&
163 ACE_Configuration::root_section () const
165 return root_;
169 * Determine if the contents of this object is the same as the
170 * contents of the object on the right hand side.
171 * Returns 1 (True) if they are equal and 0 (False) if they are not equal
173 bool
174 ACE_Configuration::operator== (const ACE_Configuration& rhs) const
176 bool rc = true;
177 int sectionIndex = 0;
178 ACE_TString sectionName;
179 ACE_Configuration *nonconst_this = const_cast<ACE_Configuration*> (this);
180 ACE_Configuration &nonconst_rhs = const_cast<ACE_Configuration&> (rhs);
182 const ACE_Configuration_Section_Key& rhsRoot = rhs.root_section ();
183 ACE_Configuration_Section_Key rhsSection;
184 ACE_Configuration_Section_Key thisSection;
186 // loop through each section in this object
187 while ((rc) && (nonconst_this->enumerate_sections (this->root_,
188 sectionIndex,
189 sectionName) == 0))
191 // find that section in the rhs object
192 if (nonconst_rhs.open_section (rhsRoot,
193 sectionName.c_str (),
195 rhsSection) != 0)
197 // If the rhs object does not contain the section then we are
198 // not equal.
199 rc = false;
201 else if (nonconst_this->open_section (this->root_,
202 sectionName.c_str (),
204 thisSection) != 0)
206 // if there is some error opening the section in this object
207 rc = false;
209 else
211 // Well the sections match
212 int valueIndex = 0;
213 ACE_TString valueName;
214 VALUETYPE valueType;
215 VALUETYPE rhsType;
217 // Enumerate each value in this section
218 while ((rc) && nonconst_this->enumerate_values (thisSection,
219 valueIndex,
220 valueName,
221 valueType) == 0)
223 // look for the same value in the rhs section
224 if (nonconst_rhs.find_value (rhsSection,
225 valueName.c_str (),
226 rhsType) != 0)
228 // We're not equal if the same value cannot
229 // be found in the rhs object.
230 rc = false;
232 else if (valueType != rhsType)
234 // we're not equal if the types do not match.
235 rc = false;
237 else
239 // finally compare values.
240 if (valueType == STRING)
242 ACE_TString thisString, rhsString;
243 if (nonconst_this->get_string_value (thisSection,
244 valueName.c_str (),
245 thisString) != 0)
247 // we're not equal if we cannot get this string
248 rc = false;
250 else if (nonconst_rhs.get_string_value (
251 rhsSection,
252 valueName.c_str (),
253 rhsString) != 0)
255 // we're not equal if we cannot get rhs string
256 rc = false;
258 rc = (thisString == rhsString);
260 else if (valueType == INTEGER)
262 u_int thisInt = 0;
263 u_int rhsInt = 0;
264 if (nonconst_this->get_integer_value (
265 thisSection,
266 valueName.c_str (),
267 thisInt) != 0)
269 // we're not equal if we cannot get this int
270 rc = false;
272 else if (nonconst_rhs.get_integer_value (
273 rhsSection,
274 valueName.c_str (),
275 rhsInt) != 0)
277 // we're not equal if we cannot get rhs int
278 rc = false;
280 rc = (thisInt == rhsInt);
282 else if (valueType == BINARY)
284 void* thisData = 0;
285 void* rhsData = 0;
286 size_t thisLength = 0;
287 size_t rhsLength = 0;
288 if (nonconst_this->get_binary_value (thisSection,
289 valueName.c_str (),
290 thisData,
291 thisLength) != 0)
293 // we're not equal if we cannot get this data
294 rc = false;
296 else if (nonconst_rhs.get_binary_value (
297 rhsSection,
298 valueName.c_str (),
299 rhsData,
300 rhsLength) != 0)
302 // we're not equal if we cannot get this data
303 rc = false;
306 rc = (thisLength == rhsLength);
307 // are the length's the same?
309 if (rc)
311 unsigned char* thisCharData =
312 (unsigned char*)thisData;
313 unsigned char* rhsCharData = (unsigned char*)rhsData;
314 // yes, then check each element
315 for (size_t count = 0;
316 (rc) && (count < thisLength);
317 count++)
319 rc = (* (thisCharData + count) == * (rhsCharData + count));
322 #if defined (ACE_HAS_ALLOC_HOOKS)
323 ACE_Allocator::instance()->free(thisCharData);
324 ACE_Allocator::instance()->free(rhsCharData);
325 #else
326 delete [] thisCharData;
327 delete [] rhsCharData;
328 #endif /* ACE_HAS_ALLOC_HOOKS */
329 }// end if the length's match
331 // We should never have valueTypes of INVALID, therefore
332 // we're not comparing them. How would we since we have
333 // no get operation for invalid types.
334 // So, if we have them, we guess they are equal.
336 }// end else if values match.
338 ++valueIndex;
339 }// end value while loop
341 // look in the rhs for values not in this
342 valueIndex = 0;
343 while ((rc) && (nonconst_rhs.enumerate_values (rhsSection,
344 valueIndex,
345 valueName,
346 rhsType) == 0))
348 // look for the same value in this section
349 if (nonconst_this->find_value (thisSection,
350 valueName.c_str (),
351 valueType) != 0)
353 // We're not equal if the same value cannot
354 // be found in the rhs object.
355 rc = false;
357 ++valueIndex;
358 }// end while for rhs values not in this.
360 }// end else if sections match.
362 ++sectionIndex;
363 }// end section while loop
365 // Finally, make sure that there are no sections in rhs that do not
366 // exist in this
367 sectionIndex = 0;
368 while ((rc)
369 && (nonconst_rhs.enumerate_sections (rhsRoot,
370 sectionIndex,
371 sectionName) == 0))
373 // find the section in this
374 if (nonconst_this->open_section (this->root_,
375 sectionName.c_str (),
377 thisSection) != 0)
379 // if there is some error opening the section in this object
380 rc = false;
382 else if (nonconst_rhs.open_section (rhsRoot,
383 sectionName.c_str (),
385 rhsSection) != 0)
387 // If the rhs object does not contain the section then we
388 // are not equal.
389 rc = false;
391 ++sectionIndex;
393 return rc;
396 bool
397 ACE_Configuration::operator!= (const ACE_Configuration& rhs) const
399 return !(*this == rhs);
402 //////////////////////////////////////////////////////////////////////////////
404 #if defined (ACE_WIN32)
406 static constexpr int ACE_DEFAULT_BUFSIZE = 256;
408 static const ACE_TCHAR *temp_name (const ACE_TCHAR *name)
410 if (name && *name == ACE_Configuration::NULL_String_)
411 return 0;
412 return name;
415 ACE_Section_Key_Win32::ACE_Section_Key_Win32 (HKEY hKey)
416 : hKey_ (hKey)
420 ACE_Section_Key_Win32::~ACE_Section_Key_Win32 ()
422 ::RegCloseKey (hKey_);
425 //////////////////////////////////////////////////////////////////////////////
427 bool
428 ACE_Configuration_Win32Registry::operator== (const ACE_Configuration_Win32Registry &rhs) const
430 ACE_UNUSED_ARG (rhs);
431 return true;
434 bool
435 ACE_Configuration_Win32Registry::operator!= (const ACE_Configuration_Win32Registry &rhs) const
437 ACE_UNUSED_ARG (rhs);
438 return true;
441 ACE_Configuration_Win32Registry::ACE_Configuration_Win32Registry (HKEY hKey, u_long security_access)
442 : security_access_ (security_access)
444 ACE_Section_Key_Win32 *temp = 0;
446 ACE_NEW (temp, ACE_Section_Key_Win32 (hKey));
448 root_ = ACE_Configuration_Section_Key (temp);
452 ACE_Configuration_Win32Registry::~ACE_Configuration_Win32Registry ()
457 ACE_Configuration_Win32Registry::open_section (const ACE_Configuration_Section_Key& base,
458 const ACE_TCHAR* sub_section,
459 bool create,
460 ACE_Configuration_Section_Key& result)
462 if (validate_name (sub_section, 1))
463 return -1;
465 HKEY base_key;
466 if (load_key (base, base_key))
467 return -1;
469 int errnum;
470 HKEY result_key;
471 if ((errnum = ACE_TEXT_RegOpenKeyEx (base_key,
472 sub_section,
474 security_access_,
475 &result_key)) != ERROR_SUCCESS)
477 if (!create)
479 errno = errnum;
480 return -1;
483 if ((errnum = ACE_TEXT_RegCreateKeyEx (base_key,
484 sub_section,
487 REG_OPTION_NON_VOLATILE,
488 security_access_,
490 &result_key,
491 (PDWORD) 0
492 )) != ERROR_SUCCESS)
494 errno = errnum;
495 return -1;
499 ACE_Section_Key_Win32 *temp;
501 ACE_NEW_RETURN (temp, ACE_Section_Key_Win32 (result_key), -1);
502 result = ACE_Configuration_Section_Key (temp);
503 return 0;
507 ACE_Configuration_Win32Registry::remove_section (const ACE_Configuration_Section_Key& key,
508 const ACE_TCHAR* sub_section,
509 bool recursive)
511 if (validate_name (sub_section))
512 return -1;
514 HKEY base_key;
515 if (load_key (key, base_key))
516 return -1;
518 if (recursive)
520 ACE_Configuration_Section_Key section;
521 if (open_section (key, sub_section, 0, section))
522 return -1;
524 HKEY sub_key;
525 if (load_key (section, sub_key))
526 return -1;
528 ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
529 DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
530 // Note we don't increment the index because the
531 // enumeration becomes invalid if we change the
532 // subkey, which we do when we delete it. By leaving
533 // it 0, we always delete the top entry
534 while (ACE_TEXT_RegEnumKeyEx (sub_key,
536 name_buffer,
537 &buffer_size,
541 0) == ERROR_SUCCESS)
543 remove_section (section, name_buffer, true);
544 buffer_size = ACE_DEFAULT_BUFSIZE;
548 int const errnum = ACE_TEXT_RegDeleteKey (base_key, sub_section);
549 if (errnum != ERROR_SUCCESS)
551 errno = errnum;
552 return -1;
555 return 0;
559 ACE_Configuration_Win32Registry::enumerate_values (const ACE_Configuration_Section_Key& key,
560 int index,
561 ACE_TString& name,
562 VALUETYPE& type)
564 HKEY base_key;
565 if (load_key (key, base_key))
566 return -1;
568 ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
569 DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
570 DWORD value_type;
572 int rc = ACE_TEXT_RegEnumValue (base_key,
573 index,
574 name_buffer,
575 &buffer_size,
577 &value_type,
580 if (rc == ERROR_NO_MORE_ITEMS)
581 return 1;
582 else if (rc != ERROR_SUCCESS)
584 errno = rc;
585 return -1;
588 name = name_buffer;
590 switch (value_type)
592 case REG_BINARY:
593 type = BINARY;
594 break;
595 case REG_SZ:
596 type = STRING;
597 break;
598 case REG_DWORD:
599 type = INTEGER;
600 break;
601 default:
602 type = INVALID;
605 return 0;
609 ACE_Configuration_Win32Registry::enumerate_sections (const ACE_Configuration_Section_Key& key,
610 int index,
611 ACE_TString& name)
613 HKEY base_key;
614 if (load_key (key, base_key))
615 return -1;
617 ACE_TCHAR name_buffer[ACE_DEFAULT_BUFSIZE];
618 DWORD buffer_size = ACE_DEFAULT_BUFSIZE;
619 int rc = ACE_TEXT_RegEnumKeyEx (base_key,
620 index,
621 name_buffer,
622 &buffer_size,
627 if (rc == ERROR_NO_MORE_ITEMS)
628 return 1;
629 else if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS)
631 errno = rc;
632 return -1;
635 name = name_buffer;
637 return 0;
641 ACE_Configuration_Win32Registry::set_string_value (const ACE_Configuration_Section_Key& key,
642 const ACE_TCHAR* name,
643 const ACE_TString& value)
645 const ACE_TCHAR *t_name = temp_name (name);
646 if (validate_value_name (t_name))
647 return -1;
649 HKEY base_key;
650 if (load_key (key, base_key))
651 return -1;
653 int errnum;
654 DWORD len = static_cast<DWORD> (value.length () + 1);
655 len *= sizeof (ACE_TCHAR);
656 if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
657 t_name,
659 REG_SZ,
660 (BYTE *) value.fast_rep (),
661 len))
662 != ERROR_SUCCESS)
664 errno = errnum;
665 return -1;
668 return 0;
672 ACE_Configuration_Win32Registry::set_integer_value (const ACE_Configuration_Section_Key& key,
673 const ACE_TCHAR* name,
674 u_int value)
676 const ACE_TCHAR *t_name = temp_name (name);
677 if (validate_value_name (t_name))
678 return -1;
680 HKEY base_key;
681 if (load_key (key, base_key))
682 return -1;
684 int errnum;
685 if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
686 t_name,
688 REG_DWORD,
689 (BYTE *) &value,
690 sizeof (value))) != ERROR_SUCCESS)
692 errno = errnum;
693 return -1;
696 return 0;
700 ACE_Configuration_Win32Registry::set_binary_value (const ACE_Configuration_Section_Key& key,
701 const ACE_TCHAR* name,
702 const void* data,
703 size_t length)
705 const ACE_TCHAR *t_name = temp_name (name);
706 if (validate_value_name (t_name))
707 return -1;
709 HKEY base_key;
710 if (load_key (key, base_key))
711 return -1;
713 int errnum;
714 if ((errnum = ACE_TEXT_RegSetValueEx (base_key,
715 t_name,
717 REG_BINARY,
718 (BYTE *) data,
719 static_cast<DWORD> (length)))
720 != ERROR_SUCCESS)
722 errno = errnum;
723 return -1;
726 return 0;
730 ACE_Configuration_Win32Registry::get_string_value (const ACE_Configuration_Section_Key& key,
731 const ACE_TCHAR* name,
732 ACE_TString& value)
734 const ACE_TCHAR *t_name = temp_name (name);
735 if (validate_value_name (t_name))
736 return -1;
738 HKEY base_key;
739 if (load_key (key, base_key))
740 return -1;
742 // Get the size of the binary data from windows
743 int errnum;
744 DWORD buffer_length = 0;
745 DWORD type;
746 if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
747 t_name,
749 &type,
750 (BYTE *) 0,
751 &buffer_length)) != ERROR_SUCCESS)
753 errno = errnum;
754 return -1;
757 if (type != REG_SZ)
759 errno = ERROR_INVALID_DATATYPE;
760 return -1;
763 ACE_TCHAR *temp = 0;
764 ACE_NEW_RETURN (temp,
765 ACE_TCHAR[buffer_length],
766 -1);
768 std::unique_ptr<ACE_TCHAR[]> buffer (temp);
770 if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
771 t_name,
773 &type,
774 (BYTE *) buffer.get (),
775 &buffer_length)) != ERROR_SUCCESS)
777 errno = errnum;
778 return -1;
781 value = buffer.get ();
782 return 0;
786 ACE_Configuration_Win32Registry::get_integer_value (const ACE_Configuration_Section_Key& key,
787 const ACE_TCHAR* name,
788 u_int& value)
790 const ACE_TCHAR *t_name = temp_name (name);
791 if (validate_value_name (t_name))
792 return -1;
794 HKEY base_key;
795 if (load_key (key, base_key))
796 return -1;
798 int errnum;
799 DWORD length = sizeof (value);
800 DWORD type;
801 if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
802 t_name,
804 &type,
805 (BYTE *) &value,
806 &length)) != ERROR_SUCCESS)
808 errno = errnum;
809 return -1;
812 if (type != REG_DWORD)
814 errno = ERROR_INVALID_DATATYPE;
815 return -1;
818 return 0;
822 ACE_Configuration_Win32Registry::get_binary_value (
823 const ACE_Configuration_Section_Key &key,
824 const ACE_TCHAR *name,
825 void *&data,
826 size_t &length)
828 const ACE_TCHAR *t_name = temp_name (name);
829 if (validate_value_name (t_name))
830 return -1;
832 HKEY base_key;
833 if (load_key (key, base_key))
834 return -1;
836 // Get the size of the binary data from windows
837 int errnum;
838 DWORD buffer_length = 0;
839 DWORD type;
840 if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
841 t_name,
843 &type,
844 (BYTE *) 0,
845 &buffer_length)) != ERROR_SUCCESS)
847 errno = errnum;
848 return -1;
851 if (type != REG_BINARY)
853 errno = ERROR_INVALID_DATATYPE;
854 return -1;
857 length = buffer_length;
859 BYTE * the_data = 0;
860 ACE_NEW_RETURN (the_data, BYTE[length], -1);
861 std::unique_ptr<BYTE[]> safe_data (the_data);
863 if ((errnum = ACE_TEXT_RegQueryValueEx (base_key,
864 t_name,
866 &type,
867 the_data,
868 &buffer_length)) != ERROR_SUCCESS)
870 data = 0;
871 errno = errnum;
872 return -1;
875 data = safe_data.release ();
877 return 0;
881 ACE_Configuration_Win32Registry::find_value (const ACE_Configuration_Section_Key& key,
882 const ACE_TCHAR* name,
883 VALUETYPE& type_out)
885 const ACE_TCHAR *t_name = temp_name (name);
886 if (validate_value_name (t_name))
887 return -1;
889 HKEY base_key;
890 if (load_key (key, base_key))
891 return -1;
893 DWORD buffer_length=0;
894 DWORD type;
895 int result=ACE_TEXT_RegQueryValueEx (base_key,
896 t_name,
898 &type,
900 &buffer_length);
901 if (result != ERROR_SUCCESS)
903 errno = result;
904 return -1;
907 switch (type)
909 case REG_SZ:
910 type_out = STRING;
911 break;
912 case REG_DWORD:
913 type_out = INTEGER;
914 break;
915 case REG_BINARY:
916 type_out = BINARY;
917 break;
918 default:
919 return -1; // unknown type
922 return 0;
926 ACE_Configuration_Win32Registry::remove_value (const ACE_Configuration_Section_Key& key,
927 const ACE_TCHAR* name)
929 const ACE_TCHAR *t_name = temp_name (name);
930 if (validate_value_name (t_name))
931 return -1;
933 HKEY base_key;
934 if (load_key (key, base_key))
935 return -1;
937 int errnum;
938 if ((errnum = ACE_TEXT_RegDeleteValue (base_key, t_name)) != ERROR_SUCCESS)
940 errno = errnum;
941 return -1;
944 return 0;
949 ACE_Configuration_Win32Registry::load_key (const ACE_Configuration_Section_Key& key,
950 HKEY& hKey)
952 ACE_Section_Key_Win32* pKey = dynamic_cast<ACE_Section_Key_Win32*> (get_internal_key (key));
953 if (!pKey)
954 return -1;
956 hKey = pKey->hKey_;
957 return 0;
960 HKEY
961 ACE_Configuration_Win32Registry::resolve_key (HKEY hKey,
962 const ACE_TCHAR* path,
963 bool create,
964 u_long security_access)
966 HKEY result = 0;
967 // Make a copy of hKey
968 int errnum;
969 if ((errnum = RegOpenKey (hKey, 0, &result)) != ERROR_SUCCESS)
971 errno = errnum;
972 return 0;
975 // recurse through the path
976 ACE_TCHAR *temp_path = 0;
977 ACE_NEW_RETURN (temp_path,
978 ACE_TCHAR[ACE_OS::strlen (path) + 1],
980 std::unique_ptr<ACE_TCHAR[]> pData (temp_path);
981 ACE_OS::strcpy (pData.get (), path);
982 ACE_Tokenizer parser (pData.get ());
983 parser.delimiter_replace ('\\', '\0');
984 parser.delimiter_replace ('/', '\0');
986 for (ACE_TCHAR *temp = parser.next ();
987 temp != 0;
988 temp = parser.next ())
990 // Open the key
991 HKEY subkey;
993 if ((errnum = ACE_TEXT_RegOpenKey (result,
994 temp,
995 &subkey)) != ERROR_SUCCESS)
997 // try creating it
998 if (!create || (errnum = ACE_TEXT_RegCreateKeyEx (result,
999 temp,
1003 security_access,
1005 &subkey,
1006 (PDWORD) 0
1007 )) !=ERROR_SUCCESS)
1009 errno = errnum;
1010 // error
1011 ::RegCloseKey (result);
1012 return 0;
1015 // release our open key handle
1016 ::RegCloseKey (result);
1017 result = subkey;
1020 return result;
1023 #endif /* ACE_WIN32 */
1025 ///////////////////////////////////////////////////////////////
1027 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId ()
1028 : type_ (ACE_Configuration::INVALID),
1029 length_ (0)
1031 this->data_.ptr_ = 0;
1034 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (ACE_TCHAR* string)
1035 : type_ (ACE_Configuration::STRING),
1036 length_ (0)
1038 this->data_.ptr_ = string;
1041 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (u_int integer)
1042 : type_ (ACE_Configuration::INTEGER),
1043 length_ (0)
1045 this->data_.int_ = integer;
1048 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (void* data, size_t length)
1049 : type_ (ACE_Configuration::BINARY),
1050 length_ (length)
1052 this->data_.ptr_ = data;
1055 ACE_Configuration_Value_IntId::ACE_Configuration_Value_IntId (const ACE_Configuration_Value_IntId& rhs)
1056 : type_ (rhs.type_),
1057 data_ (rhs.data_),
1058 length_ (rhs.length_)
1062 ACE_Configuration_Value_IntId::~ACE_Configuration_Value_IntId ()
1066 ACE_Configuration_Value_IntId& ACE_Configuration_Value_IntId::operator= (const ACE_Configuration_Value_IntId& rhs)
1068 if (this != &rhs)
1070 type_ = rhs.type_;
1071 data_ = rhs.data_;
1072 length_ = rhs.length_;
1074 return *this;
1077 void
1078 ACE_Configuration_Value_IntId::free (ACE_Allocator *alloc)
1080 if (this->type_ == ACE_Configuration::STRING
1081 || this->type_ == ACE_Configuration::BINARY)
1082 alloc->free (data_.ptr_);
1083 // Do nothing in other cases...
1086 ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_TCHAR* name)
1087 : name_ (name)
1091 ACE_Configuration_ExtId::ACE_Configuration_ExtId (const ACE_Configuration_ExtId& rhs)
1092 : name_ (rhs.name_)
1096 ACE_Configuration_ExtId& ACE_Configuration_ExtId::operator= (const ACE_Configuration_ExtId& rhs)
1098 if (this != &rhs)
1099 name_ = rhs.name_;
1101 return *this;
1104 bool
1105 ACE_Configuration_ExtId::operator== (const ACE_Configuration_ExtId& rhs) const
1107 return (ACE_OS::strcasecmp (name_, rhs.name_) == 0);
1110 bool
1111 ACE_Configuration_ExtId::operator!= (const ACE_Configuration_ExtId& rhs) const
1113 return !this->operator== (rhs);
1116 u_long
1117 ACE_Configuration_ExtId::hash () const
1119 ACE_TString temp (name_, 0, false);
1120 return temp.hash ();
1123 void
1124 ACE_Configuration_ExtId::free (ACE_Allocator *alloc)
1126 alloc->free ((void *) (name_));
1129 ///////////////////////////////////////////////////////////////////////
1131 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId ()
1132 : value_hash_map_ (0),
1133 section_hash_map_ (0)
1137 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (VALUE_MAP* value_hash_map, SUBSECTION_MAP* section_hash_map)
1138 : value_hash_map_ (value_hash_map),
1139 section_hash_map_ (section_hash_map)
1143 ACE_Configuration_Section_IntId::ACE_Configuration_Section_IntId (const ACE_Configuration_Section_IntId& rhs)
1144 : value_hash_map_ (rhs.value_hash_map_),
1145 section_hash_map_ (rhs.section_hash_map_)
1149 ACE_Configuration_Section_IntId::~ACE_Configuration_Section_IntId ()
1153 ACE_Configuration_Section_IntId&
1154 ACE_Configuration_Section_IntId::operator= (const ACE_Configuration_Section_IntId& rhs)
1156 if (this != &rhs)
1158 value_hash_map_ = rhs.value_hash_map_;
1159 section_hash_map_ = rhs.section_hash_map_;
1161 return *this;
1164 void
1165 ACE_Configuration_Section_IntId::free (ACE_Allocator *alloc)
1167 alloc->free ((void *) (value_hash_map_));
1168 alloc->free ((void *) (section_hash_map_));
1171 ACE_Configuration_Section_Key_Heap::ACE_Configuration_Section_Key_Heap (const ACE_TCHAR* path)
1172 : path_ (0),
1173 value_iter_ (0),
1174 section_iter_ (0)
1176 path_ = ACE_OS::strdup (path);
1179 ACE_Configuration_Section_Key_Heap::~ACE_Configuration_Section_Key_Heap ()
1181 delete value_iter_;
1182 delete section_iter_;
1183 #if defined (ACE_HAS_ALLOC_HOOKS)
1184 ACE_Allocator::instance()->free (path_);
1185 #else
1186 ACE_OS::free (path_);
1187 #endif /* ACE_HAS_ALLOC_HOOKS */
1190 ACE_ALLOC_HOOK_DEFINE(ACE_Configuration_Section_Key_Heap)
1192 //////////////////////////////////////////////////////////////////////////////
1194 ACE_Configuration_Heap::ACE_Configuration_Heap ()
1195 : allocator_ (nullptr),
1196 index_ (nullptr),
1197 default_map_size_ (0)
1199 ACE_Configuration_Section_Key_Heap *temp = nullptr;
1201 ACE_NEW (temp, ACE_Configuration_Section_Key_Heap (ACE_TEXT ("")));
1202 root_ = ACE_Configuration_Section_Key (temp);
1205 ACE_Configuration_Heap::~ACE_Configuration_Heap ()
1207 if (allocator_)
1208 allocator_->sync ();
1210 delete allocator_;
1214 ACE_Configuration_Heap::open (size_t default_map_size)
1216 if (this->allocator_ != 0)
1218 errno = EBUSY;
1219 return -1;
1222 default_map_size_ = default_map_size;
1223 // Create the allocator with the appropriate options.
1224 // The name used for the lock is the same as one used
1225 // for the file.
1226 ACE_NEW_RETURN (this->allocator_,
1227 HEAP_ALLOCATOR (),
1228 -1);
1229 return create_index ();
1234 ACE_Configuration_Heap::open (const ACE_TCHAR* file_name,
1235 void* base_address,
1236 size_t default_map_size)
1238 if (this->allocator_ != 0)
1240 errno = EBUSY;
1241 return -1;
1244 default_map_size_ = default_map_size;
1246 // Make sure that the file name is of the legal length.
1247 if (ACE_OS::strlen (file_name) >= MAXNAMELEN + MAXPATHLEN)
1249 errno = ENAMETOOLONG;
1250 return -1;
1253 ACE_MMAP_Memory_Pool::OPTIONS options (base_address);
1255 // Create the allocator with the appropriate options. The name used
1256 // for the lock is the same as one used for the file.
1257 ACE_NEW_RETURN (this->allocator_,
1258 PERSISTENT_ALLOCATOR (file_name,
1259 file_name,
1260 &options),
1261 -1);
1263 #if !defined (ACE_LACKS_ACCESS)
1264 // Now check if the backing store has been created successfully.
1265 if (ACE_OS::access (file_name, F_OK) != 0)
1266 ACELIB_ERROR_RETURN ((LM_ERROR,
1267 ACE_TEXT ("create_index\n")),
1268 -1);
1269 #endif /* ACE_LACKS_ACCESS */
1271 return create_index ();
1275 ACE_Configuration_Heap::create_index ()
1277 void *section_index = nullptr;
1279 // This is the easy case since if we find hash table in the
1280 // memory-mapped file we know it's already initialized.
1281 if (this->allocator_->find (ACE_CONFIG_SECTION_INDEX, section_index) == 0)
1282 this->index_ = (SECTION_MAP *) section_index;
1284 // Create a new <index_> (because we've just created a new
1285 // memory-mapped file).
1286 else
1288 size_t constexpr index_size = sizeof (SECTION_MAP);
1289 section_index = this->allocator_->malloc (index_size);
1291 if (section_index == 0
1292 || create_index_helper (section_index) == -1
1293 || this->allocator_->bind (ACE_CONFIG_SECTION_INDEX,
1294 section_index) == -1)
1296 // Attempt to clean up.
1297 ACELIB_ERROR ((LM_ERROR,
1298 ACE_TEXT ("create_index failed\n")));
1299 this->allocator_->remove ();
1300 return -1;
1302 // Add the root section
1303 return new_section (ACE_TEXT (""), root_);
1305 return 0;
1309 ACE_Configuration_Heap::create_index_helper (void *buffer)
1311 ACE_ASSERT (this->allocator_);
1312 this->index_ = new (buffer) SECTION_MAP (this->allocator_);
1313 return 0;
1317 ACE_Configuration_Heap::load_key (const ACE_Configuration_Section_Key& key,
1318 ACE_TString& name)
1320 ACE_ASSERT (this->allocator_);
1321 ACE_Configuration_Section_Key_Heap* pKey =
1322 dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
1324 if (!pKey)
1326 return -1;
1329 ACE_TString temp (pKey->path_, 0, false);
1330 name.assign_nocopy (temp);
1331 return 0;
1336 ACE_Configuration_Heap::add_section (const ACE_Configuration_Section_Key& base,
1337 const ACE_TCHAR* sub_section,
1338 ACE_Configuration_Section_Key& result)
1340 ACE_ASSERT (this->allocator_);
1341 ACE_TString section;
1342 if (load_key (base, section))
1343 return -1;
1345 // Find the base section
1346 ACE_Configuration_ExtId ExtId (section.fast_rep ());
1347 ACE_Configuration_Section_IntId IntId;
1348 if (index_->find (ExtId, IntId, allocator_))
1349 return -1;
1351 // See if this section already exists
1352 ACE_Configuration_ExtId SubSectionExtId (sub_section);
1353 int ignored = 0;
1355 if (!IntId.section_hash_map_->find (SubSectionExtId, ignored, allocator_))
1357 // already exists!
1358 errno = EEXIST;
1359 return -1;
1362 // Create the new section name
1363 // only prepend a separater if were not at the root
1364 if (section.length ())
1365 section += ACE_TEXT ("\\");
1367 section += sub_section;
1369 // Add it to the base section
1370 ACE_TCHAR* pers_name = (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (sub_section) + 1) * sizeof (ACE_TCHAR));
1371 ACE_OS::strcpy (pers_name, sub_section);
1372 ACE_Configuration_ExtId SSExtId (pers_name);
1373 if (IntId.section_hash_map_->bind (SSExtId, ignored, allocator_))
1375 allocator_->free (pers_name);
1376 return -1;
1378 return (new_section (section, result));
1382 ACE_Configuration_Heap::new_section (const ACE_TString& section,
1383 ACE_Configuration_Section_Key& result)
1385 ACE_ASSERT (this->allocator_);
1386 // Create a new section and add it to the global list
1388 // Allocate memory for items to be stored in the table.
1389 size_t const section_len = section.length () + 1;
1390 ACE_TCHAR *ptr = (ACE_TCHAR*) this->allocator_->malloc (section_len * sizeof (ACE_TCHAR));
1392 int return_value = -1;
1394 if (ptr == 0)
1395 return -1;
1396 else
1398 // Populate memory with data.
1399 ACE_OS::strcpy (ptr, section.fast_rep ());
1401 size_t constexpr map_size = sizeof (VALUE_MAP);
1402 void *value_hash_map = this->allocator_->malloc (map_size);
1404 // If allocation failed ...
1405 if (value_hash_map == nullptr)
1406 return -1;
1408 // Initialize allocated hash map through placement new.
1409 if (value_open_helper (default_map_size_, value_hash_map ) == -1)
1411 this->allocator_->free (value_hash_map );
1412 return -1;
1415 // create the section map
1416 size_t constexpr subsection_map_size = sizeof (SUBSECTION_MAP);
1417 void* section_hash_map = this->allocator_->malloc (subsection_map_size);
1419 // If allocation failed
1420 if (section_hash_map == nullptr)
1421 return -1;
1423 // initialize allocated hash map through placement new
1424 if (section_open_helper (default_map_size_, section_hash_map) == -1)
1426 this->allocator_->free (value_hash_map );
1427 this->allocator_->free (section_hash_map);
1428 return -1;
1431 ACE_Configuration_ExtId name (ptr);
1432 ACE_Configuration_Section_IntId entry ((VALUE_MAP*) value_hash_map,
1433 (SUBSECTION_MAP*) section_hash_map);
1435 // Do a normal bind. This will fail if there's already an
1436 // entry with the same name.
1437 return_value = this->index_->bind (name, entry, this->allocator_);
1439 if (return_value == 1 /* Entry already existed so bind failed. */
1440 || return_value == -1 /* Unable to bind for other reasons. */)
1442 // Free our dynamically allocated memory.
1443 this->allocator_->free (static_cast<void *> (ptr));
1444 return return_value;
1447 // If bind () succeed, it will automatically sync
1448 // up the map manager entry. However, we must sync up our
1449 // name/value memory.
1450 this->allocator_->sync (ptr, section_len);
1453 // set the result
1454 ACE_Configuration_Section_Key_Heap *temp = nullptr;
1455 ACE_NEW_RETURN (temp,
1456 ACE_Configuration_Section_Key_Heap (ptr),
1457 -1);
1458 result = ACE_Configuration_Section_Key (temp);
1459 return return_value;
1463 ACE_Configuration_Heap::value_open_helper (size_t hash_table_size,
1464 void *buffer)
1466 ACE_ASSERT (this->allocator_);
1467 new (buffer) VALUE_MAP (hash_table_size, this->allocator_);
1468 return 0;
1472 ACE_Configuration_Heap::section_open_helper (size_t hash_table_size,
1473 void *buffer)
1475 ACE_ASSERT (this->allocator_);
1476 new (buffer) SUBSECTION_MAP (hash_table_size, this->allocator_);
1477 return 0;
1481 ACE_Configuration_Heap::open_section (const ACE_Configuration_Section_Key& base,
1482 const ACE_TCHAR* sub_section,
1483 bool create,
1484 ACE_Configuration_Section_Key& result)
1486 ACE_ASSERT (this->allocator_);
1487 if (validate_name (sub_section, 1)) // 1 == allow_path
1488 return -1;
1490 result = base;
1492 for (const ACE_TCHAR* separator = nullptr;
1493 (separator = ACE_OS::strchr (sub_section, ACE_TEXT ('\\'))) != nullptr;
1496 // Create a substring from the current location until the new found separator
1497 // Because both separator and sub_section are ACE_TCHAR*, the character size is
1498 // already taken into account.
1499 ACE_TString tsub_section (sub_section);
1500 ACE_TString const simple_section = tsub_section.substring(0, separator - sub_section);
1501 int const ret_val = open_simple_section (result, simple_section.c_str(), create, result);
1502 if (ret_val)
1503 return ret_val;
1504 sub_section = separator + 1;
1507 return open_simple_section (result, sub_section, create, result);
1511 ACE_Configuration_Heap::open_simple_section (const ACE_Configuration_Section_Key& base,
1512 const ACE_TCHAR* sub_section,
1513 bool create,
1514 ACE_Configuration_Section_Key& result)
1516 ACE_TString section (0, 0, false);
1518 if (load_key (base, section))
1520 return -1;
1523 // Only add the \\ if were not at the root
1524 if (section.length ())
1526 section += ACE_TEXT ("\\");
1529 section += sub_section;
1531 // resolve the section
1532 ACE_Configuration_ExtId ExtId (section.fast_rep ());
1533 ACE_Configuration_Section_IntId IntId;
1535 if (index_->find (ExtId, IntId, allocator_))
1537 if (!create)
1539 errno = ENOENT;
1540 return -1;
1543 return add_section (base, sub_section, result);
1546 ACE_Configuration_Section_Key_Heap *temp;
1547 ACE_NEW_RETURN (temp,
1548 ACE_Configuration_Section_Key_Heap (section.fast_rep ()),
1549 -1);
1550 result = ACE_Configuration_Section_Key (temp);
1551 return 0;
1555 ACE_Configuration_Heap::remove_section (const ACE_Configuration_Section_Key& key,
1556 const ACE_TCHAR* sub_section,
1557 bool recursive)
1559 ACE_ASSERT (this->allocator_);
1560 if (validate_name (sub_section))
1561 return -1;
1563 ACE_TString section;
1564 if (load_key (key, section))
1565 return -1;
1567 // Find this key
1568 ACE_Configuration_ExtId ParentExtId (section.fast_rep ());
1569 ACE_Configuration_Section_IntId ParentIntId;
1570 if (index_->find (ParentExtId, ParentIntId, allocator_))
1571 return -1;// no parent key
1573 // Find this subkey
1574 if (section.length ())
1575 section += ACE_TEXT ("\\");
1577 section += sub_section;
1578 ACE_Configuration_ExtId SectionExtId (section.fast_rep ());
1579 SECTION_HASH::ENTRY* section_entry = nullptr;
1580 SECTION_HASH* hashmap = index_;
1581 if (hashmap->find (SectionExtId, section_entry))
1582 return -1;
1584 if (recursive)
1586 ACE_Configuration_Section_Key recursive_section;
1587 if (open_section (key, sub_section, 0, recursive_section))
1588 return -1;
1590 int index = 0;
1591 ACE_TString name;
1592 while (!enumerate_sections (recursive_section, index, name))
1594 if (remove_section (recursive_section, name.fast_rep (), true))
1595 return -1;
1597 ++index;
1601 // Now make sure we dont have any subkeys
1602 if (section_entry->int_id_.section_hash_map_->current_size ())
1604 errno = ENOTEMPTY;
1605 return -1;
1608 // Now remove subkey from parent key
1609 ACE_Configuration_ExtId SubSExtId (sub_section);
1610 SUBSECTION_HASH::ENTRY* subsection_entry = nullptr;
1611 if (((SUBSECTION_HASH*)ParentIntId.section_hash_map_)->
1612 find (SubSExtId, subsection_entry))
1613 return -1;
1615 if (ParentIntId.section_hash_map_->unbind (SubSExtId, allocator_))
1616 return -1;
1618 subsection_entry->ext_id_.free (allocator_);
1620 // Remember the pointers so we can free them after we unbind
1621 ACE_Configuration_ExtId ExtIdToFree (section_entry->ext_id_);
1622 ACE_Configuration_Section_IntId IntIdToFree (section_entry->int_id_);
1624 // iterate over all values and free memory
1625 VALUE_HASH* value_hash_map = section_entry->int_id_.value_hash_map_;
1626 VALUE_HASH::ITERATOR value_iter = value_hash_map->begin ();
1627 while (!value_iter.done ())
1629 VALUE_HASH::ENTRY* value_entry = 0;
1630 if (!value_iter.next (value_entry))
1631 return 1;
1633 value_entry->ext_id_.free (allocator_);
1634 value_entry->int_id_.free (allocator_);
1636 value_iter.advance ();
1639 // remove it
1640 if (index_->unbind (SectionExtId, allocator_))
1641 return -1;
1643 value_hash_map->close ();
1644 section_entry->int_id_.section_hash_map_->close (allocator_);
1646 // Free the memory
1647 ExtIdToFree.free (allocator_);
1648 IntIdToFree.free (allocator_);
1650 return 0;
1654 ACE_Configuration_Heap::enumerate_values (const ACE_Configuration_Section_Key& key,
1655 int index,
1656 ACE_TString& name,
1657 VALUETYPE& type)
1659 ACE_ASSERT (this->allocator_);
1660 ACE_Configuration_Section_Key_Heap* pKey =
1661 dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
1662 if (!pKey)
1663 return -1;
1665 name = pKey->path_;
1667 // resolve the section
1668 ACE_Configuration_ExtId ExtId (pKey->path_);
1669 ACE_Configuration_Section_IntId IntId;
1670 if (index_->find (ExtId, IntId, allocator_))
1671 return -1;
1673 // Handle iterator resets
1674 if (index == 0)
1676 ACE_Hash_Map_Manager_Ex<ACE_Configuration_ExtId ,
1677 ACE_Configuration_Value_IntId,
1678 ACE_Hash<ACE_Configuration_ExtId>,
1679 ACE_Equal_To<ACE_Configuration_ExtId>,
1680 ACE_Null_Mutex>* hash_map = IntId.value_hash_map_;
1681 delete pKey->value_iter_;
1683 ACE_NEW_RETURN (pKey->value_iter_,
1684 VALUE_HASH::ITERATOR (hash_map->begin ()),
1685 -1);
1688 // Get the next entry
1689 ACE_Hash_Map_Entry<ACE_Configuration_ExtId, ACE_Configuration_Value_IntId>* entry = 0;
1691 if (!pKey->value_iter_->next (entry))
1692 return 1;
1694 // Return the value of the iterator and advance it
1695 name = entry->ext_id_.name_;
1696 type = entry->int_id_.type_;
1697 pKey->value_iter_->advance ();
1699 return 0;
1703 ACE_Configuration_Heap::enumerate_sections (const ACE_Configuration_Section_Key& key,
1704 int index,
1705 ACE_TString& name)
1707 ACE_ASSERT (this->allocator_);
1708 // cast to a heap section key
1709 ACE_Configuration_Section_Key_Heap* pKey =
1710 dynamic_cast<ACE_Configuration_Section_Key_Heap*> (get_internal_key (key));
1711 if (!pKey)
1712 return -1; // not a heap key!
1714 // resolve the section
1715 ACE_Configuration_ExtId ExtId (pKey->path_);
1716 ACE_Configuration_Section_IntId IntId;
1717 if (index_->find (ExtId, IntId, allocator_))
1718 return -1; // unknown section
1720 // Handle iterator resets
1721 if (index == 0)
1723 if (pKey->section_iter_)
1724 delete pKey->section_iter_;
1726 ACE_NEW_RETURN (pKey->section_iter_,
1727 SUBSECTION_HASH::ITERATOR (IntId.section_hash_map_->begin ()),
1728 -1);
1731 // Get the next entry
1732 ACE_Hash_Map_Entry<ACE_Configuration_ExtId, int>* entry = 0;
1733 if (!pKey->section_iter_->next (entry))
1734 return 1;
1736 // Return the value of the iterator and advance it
1737 pKey->section_iter_->advance ();
1738 name = entry->ext_id_.name_;
1740 return 0;
1744 ACE_Configuration_Heap::set_string_value (const ACE_Configuration_Section_Key& key,
1745 const ACE_TCHAR* name,
1746 const ACE_TString& value)
1748 ACE_ASSERT (this->allocator_);
1749 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
1750 if (validate_value_name (t_name))
1751 return -1;
1753 ACE_TString section;
1754 if (load_key (key, section))
1755 return -1;
1757 ACE_Configuration_ExtId section_ext (section.fast_rep ());
1758 ACE_Configuration_Section_IntId section_int;
1759 if (index_->find (section_ext, section_int, allocator_))
1760 return -1;
1762 // Get the entry for this item (if it exists)
1763 VALUE_HASH::ENTRY* entry = 0;
1764 ACE_Configuration_ExtId item_name (t_name);
1765 if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
1767 // found item, replace it
1768 // Free the old value
1769 entry->int_id_.free (allocator_);
1770 // Allocate the new value in this heap
1771 ACE_TCHAR* pers_value =
1772 (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
1773 ACE_OS::strcpy (pers_value, value.fast_rep ());
1774 ACE_Configuration_Value_IntId new_value_int (pers_value);
1775 entry->int_id_ = new_value_int;
1777 else
1779 // it doesn't exist, bind it
1780 ACE_TCHAR* pers_name =
1781 (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
1782 ACE_OS::strcpy (pers_name, t_name);
1783 ACE_TCHAR* pers_value =
1784 (ACE_TCHAR *) allocator_->malloc ((value.length () + 1) * sizeof (ACE_TCHAR));
1785 ACE_OS::strcpy (pers_value, value.fast_rep ());
1786 ACE_Configuration_ExtId new_item_name (pers_name);
1787 ACE_Configuration_Value_IntId item_value (pers_value);
1788 if (section_int.value_hash_map_->bind (new_item_name, item_value, allocator_))
1790 allocator_->free (pers_value);
1791 allocator_->free (pers_name);
1792 return -1;
1794 return 0;
1797 return 0;
1801 ACE_Configuration_Heap::set_integer_value (const ACE_Configuration_Section_Key& key,
1802 const ACE_TCHAR* name,
1803 u_int value)
1805 ACE_ASSERT (this->allocator_);
1806 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
1807 if (validate_value_name (t_name))
1808 return -1;
1810 // Get the section name from the key
1811 ACE_TString section;
1812 if (load_key (key, section))
1813 return -1;
1815 // Find this section
1816 ACE_Configuration_ExtId section_ext (section.fast_rep ());
1817 ACE_Configuration_Section_IntId section_int;
1818 if (index_->find (section_ext, section_int, allocator_))
1819 return -1; // section does not exist
1821 // Get the entry for this item (if it exists)
1822 VALUE_HASH::ENTRY* entry = 0;
1823 ACE_Configuration_ExtId item_name (t_name);
1824 if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
1826 // found item, replace it
1827 ACE_Configuration_Value_IntId new_value_int (value);
1828 entry->int_id_ = new_value_int;
1830 else
1832 // it doesn't exist, bind it
1833 ACE_TCHAR* pers_name =
1834 (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
1835 ACE_OS::strcpy (pers_name, t_name);
1836 ACE_Configuration_ExtId item_name (pers_name);
1837 ACE_Configuration_Value_IntId item_value (value);
1838 if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
1840 allocator_->free (pers_name);
1841 return -1;
1843 return 0;
1846 return 0;
1850 ACE_Configuration_Heap::set_binary_value (const ACE_Configuration_Section_Key& key,
1851 const ACE_TCHAR* name,
1852 const void* data,
1853 size_t length)
1855 ACE_ASSERT (this->allocator_);
1856 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
1857 if (validate_value_name (t_name))
1858 return -1;
1860 // Get the section name from the key
1861 ACE_TString section;
1862 if (load_key (key, section))
1863 return -1;
1865 // Find this section
1866 ACE_Configuration_ExtId section_ext (section.fast_rep ());
1867 ACE_Configuration_Section_IntId section_int;
1868 if (index_->find (section_ext, section_int, allocator_))
1869 return -1; // section does not exist
1871 // Get the entry for this item (if it exists)
1872 VALUE_HASH::ENTRY* entry = 0;
1873 ACE_Configuration_ExtId item_name (t_name);
1874 if (section_int.value_hash_map_->VALUE_HASH::find (item_name, entry) == 0)
1876 // found item, replace it
1877 // Free the old value
1878 entry->int_id_.free (allocator_);
1879 // Allocate the new value in this heap
1880 ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
1881 ACE_OS::memcpy (pers_value, data, length);
1882 ACE_Configuration_Value_IntId new_value_int (pers_value, length);
1883 entry->int_id_ = new_value_int;
1885 else
1887 // it doesn't exist, bind it
1888 ACE_TCHAR* pers_name =
1889 (ACE_TCHAR *) allocator_->malloc ((ACE_OS::strlen (t_name) + 1) * sizeof (ACE_TCHAR));
1890 ACE_OS::strcpy (pers_name, t_name);
1891 ACE_TCHAR* pers_value = (ACE_TCHAR *) allocator_->malloc (length);
1892 ACE_OS::memcpy (pers_value, data, length);
1893 ACE_Configuration_ExtId item_name (pers_name);
1894 ACE_Configuration_Value_IntId item_value (pers_value, length);
1895 if (section_int.value_hash_map_->bind (item_name, item_value, allocator_))
1897 allocator_->free (pers_value);
1898 allocator_->free (pers_name);
1899 return -1;
1901 return 0;
1904 return 0;
1908 ACE_Configuration_Heap::get_string_value (const ACE_Configuration_Section_Key& key,
1909 const ACE_TCHAR* name,
1910 ACE_TString& value)
1912 ACE_ASSERT (this->allocator_);
1913 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
1914 if (validate_value_name (t_name))
1915 return -1;
1917 // Get the section name from the key
1918 ACE_TString section;
1919 if (load_key (key, section))
1920 return -1;
1922 // Find this section
1923 ACE_Configuration_ExtId ExtId (section.fast_rep ());
1924 ACE_Configuration_Section_IntId IntId;
1925 if (index_->find (ExtId, IntId, allocator_))
1926 return -1; // section does not exist
1928 // See if it exists first
1929 ACE_Configuration_ExtId VExtId (t_name);
1930 ACE_Configuration_Value_IntId VIntId;
1931 if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
1932 return -1; // unknown value
1934 // Check type
1935 if (VIntId.type_ != ACE_Configuration::STRING)
1937 errno = ENOENT;
1938 return -1;
1941 // everythings ok, return the data
1942 value = static_cast<ACE_TCHAR*> (VIntId.data_.ptr_);
1943 return 0;
1947 ACE_Configuration_Heap::get_integer_value (const ACE_Configuration_Section_Key& key,
1948 const ACE_TCHAR* name,
1949 u_int& value)
1951 ACE_ASSERT (this->allocator_);
1953 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
1954 if (validate_value_name (t_name))
1955 return -1;
1957 // Get the section name from the key
1958 ACE_TString section (0, 0, false);
1960 if (this->load_key (key, section) != 0)
1962 return -1;
1965 // Find this section
1966 ACE_Configuration_ExtId ExtId (section.fast_rep ());
1967 ACE_Configuration_Section_IntId IntId;
1969 if (index_->find (ExtId, IntId, allocator_) != 0)
1971 return -1; // section does not exist
1975 // See if it exists first
1976 ACE_Configuration_ExtId VExtId (t_name);
1977 ACE_Configuration_Value_IntId VIntId;
1979 if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_) != 0)
1981 return -1; // unknown value
1984 // Check type
1985 if (VIntId.type_ != ACE_Configuration::INTEGER)
1987 errno = ENOENT;
1988 return -1;
1991 // Everythings ok, return the data
1992 value = VIntId.data_.int_;
1993 return 0;
1997 ACE_Configuration_Heap::get_binary_value (
1998 const ACE_Configuration_Section_Key& key,
1999 const ACE_TCHAR* name,
2000 void*& data,
2001 size_t& length)
2003 ACE_ASSERT (this->allocator_);
2004 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
2005 if (validate_value_name (t_name))
2006 return -1;
2008 // Get the section name from the key
2009 ACE_TString section;
2010 if (load_key (key, section))
2011 return -1;
2013 // Find this section
2014 ACE_Configuration_ExtId ExtId (section.fast_rep ());
2015 ACE_Configuration_Section_IntId IntId;
2016 if (index_->find (ExtId, IntId, allocator_))
2017 return -1; // section does not exist
2019 ACE_Configuration_ExtId VExtId (t_name);
2020 ACE_Configuration_Value_IntId VIntId;
2021 // See if it exists first
2022 if (IntId.value_hash_map_->find (VExtId, VIntId, allocator_))
2023 return -1; // unknown value
2025 // Check type
2026 if (VIntId.type_ != ACE_Configuration::BINARY)
2028 errno = ENOENT;
2029 return -1;
2032 // Make a copy
2033 #if defined (ACE_HAS_ALLOC_HOOKS)
2034 ACE_ALLOCATOR_RETURN (data, static_cast<char*> (ACE_Allocator::instance()->malloc(sizeof(char) * VIntId.length_)), -1);
2035 #else
2036 ACE_NEW_RETURN (data, char[VIntId.length_], -1);
2037 #endif /* ACE_HAS_ALLOC_HOOKS */
2038 ACE_OS::memcpy (data, VIntId.data_.ptr_, VIntId.length_);
2039 length = VIntId.length_;
2040 return 0;
2044 ACE_Configuration_Heap::find_value (const ACE_Configuration_Section_Key& key,
2045 const ACE_TCHAR* name,
2046 VALUETYPE& type_out)
2048 ACE_ASSERT (this->allocator_);
2049 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
2050 if (validate_value_name (t_name))
2051 return -1;
2053 // Get the section name from the key
2054 ACE_TString section;
2055 if (load_key (key, section))
2056 return -1;
2058 // Find this section
2059 ACE_Configuration_ExtId ExtId (section.fast_rep ());
2060 ACE_Configuration_Section_IntId IntId;
2061 if (index_->find (ExtId, IntId, allocator_))
2062 return -1; // section does not exist
2064 // Find it
2065 ACE_Configuration_ExtId ValueExtId (t_name);
2066 VALUE_HASH::ENTRY* value_entry = 0;
2067 if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
2068 return -1; // value does not exist
2070 type_out = value_entry->int_id_.type_;
2071 return 0;
2075 ACE_Configuration_Heap::remove_value (const ACE_Configuration_Section_Key& key,
2076 const ACE_TCHAR* name)
2078 ACE_ASSERT (this->allocator_);
2079 const ACE_TCHAR *t_name = name ? name : &this->NULL_String_;
2080 if (validate_value_name (t_name))
2081 return -1;
2083 // Get the section name from the key
2084 ACE_TString section;
2085 if (load_key (key, section))
2086 return -1;
2088 // Find this section
2089 ACE_Configuration_ExtId ExtId (section.fast_rep ());
2090 ACE_Configuration_Section_IntId IntId;
2091 if (index_->find (ExtId, IntId, allocator_))
2092 return -1; // section does not exist
2094 // Find it
2095 ACE_Configuration_ExtId ValueExtId (t_name);
2096 VALUE_HASH::ENTRY* value_entry = 0;
2097 if (((VALUE_HASH *) IntId.value_hash_map_)->find (ValueExtId, value_entry))
2098 return -1;
2100 // free it
2101 value_entry->ext_id_.free (allocator_);
2102 value_entry->int_id_.free (allocator_);
2104 // Unbind it
2105 if (IntId.value_hash_map_->unbind (ValueExtId, allocator_))
2106 return -1;
2108 return 0;
2111 ACE_END_VERSIONED_NAMESPACE_DECL