commreg.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:56k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. // #include <stdio.h>
  37. #include "hlxclib/stdlib.h"
  38. #include "hlxclib/string.h"
  39. #include "hxtypes.h"
  40. #include "debug.h"
  41. #include "ihxpckts.h"
  42. #include "hxmon.h"
  43. #include "hxstrutl.h"
  44. #include "chxpckts.h"
  45. #include "db_misc.h"
  46. #include "key.h"
  47. #include "watchlst.h"
  48. #include "property.h"
  49. #include "db_dict_abs.h"
  50. #include "db_dict.h"
  51. #include "id.h"
  52. #include "commreg.h"
  53. #include "hxheap.h"
  54. #ifdef _DEBUG
  55. #undef HX_THIS_FILE
  56. static const char HX_THIS_FILE[] = __FILE__;
  57. #endif
  58. CommonRegistry::CommonRegistry()
  59.               : _count(0)
  60.       , m_pWatchList(NULL)
  61.       , m_lWatchCount(0)
  62.       , m_LastError(HXR_OK)
  63. {
  64.     _logdb_imp = new DB_dict;
  65.     if(!_logdb_imp)
  66.     {
  67.         m_LastError = HXR_OUTOFMEMORY;
  68.     }
  69.     _ids = new CHXID(1000);
  70.     if(!_ids)
  71.     {
  72.         m_LastError = HXR_OUTOFMEMORY;
  73.     }
  74.     DPRINTF(D_REGISTRY, ("CommonRegistry::CommonRegistry -- _logdb_imp(%p), "
  75.                          "_ids(%p)n", _logdb_imp, _ids));
  76. }
  77. CommonRegistry::~CommonRegistry()
  78. {
  79.     if (_logdb_imp)
  80. delete _logdb_imp;
  81.     if (_ids)
  82. delete _ids;
  83. }
  84. /*
  85.  *  Function Name:   AddComp
  86.  *  Input Params:    char * prop_name
  87.  *  Return Value:    UINT32
  88.  *  Description:
  89.  *   function for adding PT_COMPOSITE nodes in the log database.
  90.  *  PT_COMPOSITE nodes can contain other nodes, this is the structure
  91.  *  demanded by the hierarchical storage.
  92.  */
  93. UINT32
  94. CommonRegistry::AddComp(const char* prop_name)
  95. {
  96.     DPRINTF(D_REGISTRY, ("CommonRegistry::AddComp(%s)n", prop_name));
  97.     HX_RESULT theErr = HXR_OK;
  98.     DB_node* d = 0;
  99.     Property* p = 0;
  100.     Key* k = new Key(prop_name);
  101.     if(!k)
  102.     {
  103.         return 0;
  104.     }
  105.     int len = k->size();
  106.     char* curr_key_str = new char[len];
  107.     if(!curr_key_str)
  108.     {
  109.         HX_DELETE(k);
  110.         return 0;
  111.     }
  112.     DB_implem* ldb = _logdb_imp;
  113.     DB_node* new_d = NULL;
  114.     BOOL read_only = FALSE;
  115.     /*
  116.      * check if all but the last sub-strings are already present
  117.      * eg.
  118.      *     if foo.bar.moo is to be added then
  119.      *        the following loop checks is "foo" and "bar"
  120.      *        have already been created
  121.      *     after the while loop one final check is made to check
  122.      *     if "moo" NOT already present to avoid adding a DUPLICATE
  123.      */
  124.     *curr_key_str = '';
  125.     while(!k->last_sub_str())
  126.     {
  127.         k->append_sub_str(curr_key_str, len);
  128. if (p && p->get_type() == PT_COMPOSITE)
  129.     p->get_db_val(&ldb);
  130. if (!ldb)
  131. {
  132.     DPRINTF(D_INFO, ("%s -- %s has NO Properties under it!n",
  133.    prop_name, curr_key_str));
  134.     theErr = HXR_FAILED;
  135.     goto cleanup;
  136. }
  137. d = ldb->find(curr_key_str);
  138. if (!d)
  139. {
  140.     DPRINTF(D_REGISTRY, ("%s -- %s was NOT FOUNDn",
  141.                          prop_name, curr_key_str));
  142.     theErr = HXR_FAILED;
  143.     goto cleanup;
  144. }
  145. p = d->get_data();
  146.         if (!p)
  147. {
  148.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  149.                          prop_name, curr_key_str));
  150.     theErr = HXR_FAILED;
  151.     goto cleanup;
  152. }
  153. read_only = p->is_read_only();
  154. if (read_only)
  155. {
  156.     DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLYn",
  157.                          prop_name, curr_key_str));
  158.     theErr = HXR_FAILED;
  159.     goto cleanup;
  160. }
  161.     }
  162.     if (p && p->get_type() == PT_COMPOSITE)
  163. p->get_db_val(&ldb);
  164.     k->append_sub_str(curr_key_str, len);
  165.     if (ldb->find(curr_key_str))
  166.     {
  167. DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!n", k->get_key_str()));
  168. theErr = HXR_FAILED;
  169. goto cleanup;
  170.     }
  171.     // everything is alright add the new property
  172.     new_d = _addComp(k, curr_key_str, ldb);
  173.     AddDone(ldb, new_d, d, p);
  174. cleanup:
  175.     HX_VECTOR_DELETE(curr_key_str);
  176.     if (HXR_OK != theErr)
  177.     {
  178. if (k)
  179. {
  180.     delete k;
  181.     k = NULL;
  182. }
  183. return 0;
  184.     }
  185.     else
  186.     {
  187. return new_d->get_id();
  188.     }
  189. }
  190. UINT32
  191. CommonRegistry::_buildSubstructure4Prop(const char* pFailurePoint,
  192. const char* pProp)
  193. {
  194.     /*
  195.      * A lower composite was not there.
  196.      * Add all of the composites up the to prop.
  197.      */
  198.     UINT32 len = strlen(pProp) + 1;
  199.     Key* lame = new Key(pProp);
  200.     char* temp_key_str = new char[len];
  201.     *temp_key_str = 0;
  202.     while (strlen(temp_key_str) < strlen(pFailurePoint))
  203.     {
  204. lame->append_sub_str(temp_key_str, len);
  205.     }
  206.     int ret;
  207.     while ((ret = AddComp(temp_key_str)) != 0)
  208.     {
  209. if (lame->last_sub_str())
  210. {
  211.     break;
  212. }
  213. lame->append_sub_str(temp_key_str, len);
  214.     }
  215.     delete[] temp_key_str;
  216.     delete lame;
  217.     lame = 0;
  218.     return ret;
  219. }
  220. /*
  221.  *  Function Name:   AddInt
  222.  *  Input Params:    const char* prop_name, const INT32 val
  223.  *  Return Value:    UINT32
  224.  *  Description:
  225.  *   function to add a property which has an integer value, to
  226.  *  the log database. this will add all the USER DEFINED properties.
  227.  */
  228. UINT32
  229. CommonRegistry::AddInt(const char* prop_name, const INT32 val)
  230. {
  231.     DPRINTF(D_REGISTRY, ("CommonRegistry::AddInt(%s, %ld)n", prop_name, val));
  232.     HX_RESULT theErr = HXR_OK;
  233.     DB_node* d = 0;
  234.     Property* p = 0;
  235.     Key* k = new Key(prop_name);
  236.     if(!k)
  237.     {
  238.         return 0;
  239.     }
  240.     int len = k->size();
  241.     char* curr_key_str = new char[len];
  242.     if(!curr_key_str)
  243.     {
  244.         HX_DELETE(k);
  245.         return 0;
  246.     }
  247.     DB_implem* ldb = _logdb_imp;
  248.     DB_node* new_d = NULL;
  249.     BOOL read_only = FALSE;
  250.     *curr_key_str = '';
  251.     while(!k->last_sub_str())
  252.     {
  253.         k->append_sub_str(curr_key_str, len);
  254. if (p && p->get_type() == PT_COMPOSITE)
  255.     p->get_db_val(&ldb);
  256. if (!ldb)
  257. {
  258.     DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!n",
  259.                          prop_name, curr_key_str));
  260.     theErr = HXR_FAILED;
  261.     goto cleanup;
  262. }
  263. d = ldb->find(curr_key_str);
  264. if (!d)
  265. {
  266.     int ret = _buildSubstructure4Prop(curr_key_str,
  267. prop_name);
  268.     if (ret)
  269.     {
  270. d = ldb->find(curr_key_str);
  271.     }
  272.     if (!ret || !d)
  273.     {
  274. theErr = HXR_FAILED;
  275. goto cleanup;
  276.     }
  277. }
  278. p = d->get_data();
  279.         if (!p)
  280. {
  281.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  282.                          prop_name, curr_key_str));
  283.     theErr = HXR_FAILED;
  284.     goto cleanup;
  285. }
  286. read_only = p->is_read_only();
  287. if (read_only)
  288. {
  289.     DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLYn",
  290.                          prop_name, curr_key_str));
  291.     theErr = HXR_FAILED;
  292.     goto cleanup;
  293. }
  294.     }
  295.     if (p && p->get_type() == PT_COMPOSITE)
  296. p->get_db_val(&ldb);
  297.     k->append_sub_str(curr_key_str, len);
  298.     if (ldb->find(curr_key_str))
  299.     {
  300. DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!n", k->get_key_str()));
  301. theErr = HXR_FAILED;
  302. goto cleanup;
  303.     }
  304.     // everything is alright add the new property
  305.     new_d = _addInt(k, curr_key_str, val, ldb);
  306.     AddDone(ldb, new_d, d, p);
  307. cleanup:
  308.     HX_VECTOR_DELETE(curr_key_str);
  309.     if (HXR_OK != theErr)
  310.     {
  311. if (k)
  312. {
  313.     delete k;
  314.     k = NULL;
  315. }
  316. return 0;
  317.     }
  318.     else
  319.     {
  320. return new_d->get_id();
  321.     }
  322. }
  323. /*
  324.  *  Function Name:   GetInt
  325.  *  Input Params:    const char* prop_name, INT32* value
  326.  *  Return Value:    HX_RESULT
  327.  *  Description:
  328.  *   retrieve the INTEGER property if it exists.
  329.  */
  330. HX_RESULT
  331. CommonRegistry::GetInt(const char* prop_name, INT32* value) const
  332. {
  333.     DB_node*  d = 0;
  334.     Property* p = 0;
  335.     if (_find(&d, &p, prop_name) != HXR_OK)
  336. return HXR_FAIL;
  337.     if (p)
  338.     {
  339. switch(p->get_type())
  340. {
  341.     case PT_INTEGER:
  342. return p->get_int_val(value);
  343. break;
  344.     case PT_INTREF:
  345. return p->get_int_ref_val(value);
  346. break;
  347.     default:
  348. DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  349.                      prop_name));
  350. return HXR_PROP_TYPE_MISMATCH;
  351. }
  352.     }
  353.     return HXR_FAIL;
  354. }
  355. /*
  356.  *  Function Name:   GetInt
  357.  *  Input Params:    const UINT32 hash_key, INT32* value
  358.  *  Return Value:    HX_RESULT
  359.  *  Description:
  360.  *   retrieve the INTEGER property using the HashTree.
  361.  */
  362. HX_RESULT
  363. CommonRegistry::GetInt(const UINT32 hash_key, INT32* value) const
  364. {
  365.     DB_node*  d = 0;
  366.     Property* p = 0;
  367.     d = (DB_node *)_ids->get(hash_key);
  368.     if (!d)
  369.     {
  370. DPRINTF(D_REGISTRY, ("GetInt(%lu) failedn", hash_key));
  371. return HXR_FAIL;
  372.     }
  373.     p = d->get_data();
  374.     if (p)
  375.     {
  376. switch(p->get_type())
  377. {
  378.     case PT_INTEGER:
  379. return p->get_int_val(value);
  380. break;
  381.     case PT_INTREF:
  382. return p->get_int_ref_val(value);
  383. break;
  384.     default:
  385. DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  386.                      hash_key));
  387. return HXR_PROP_TYPE_MISMATCH;
  388. }
  389.     }
  390.     return HXR_FAIL;
  391. }
  392. /*
  393.  *  Function Name:   SetInt
  394.  *  Input Params:    const char* prop_name, const INT32 value
  395.  *  Return Value:    HX_RESULT
  396.  *  Description:
  397.  *   sets the value of an integer property.
  398.  */
  399. HX_RESULT
  400. CommonRegistry::SetInt(const char* prop_name, const INT32 value)
  401. {
  402.     DB_node*  d = 0;
  403.     Property* p = 0;
  404.     if (_find(&d, &p, prop_name) != HXR_OK)
  405. return HXR_FAIL;
  406.     if (!p)
  407.         return HXR_FAIL;
  408.     if (p->is_read_only())
  409.     {
  410.         DPRINTF(D_REGISTRY, ("%s -- Property is READ ONLYn",
  411.                      prop_name));
  412. return HXR_FAIL;
  413.     }
  414.     switch(p->get_type())
  415.     {
  416.         case PT_INTEGER:
  417.             p->int_val(value);
  418.             break;
  419.         case PT_INTREF:
  420.             DPRINTF(D_REGISTRY, ("cannot set INTREF value using SetIntn"));
  421.             return HXR_FAIL;
  422.         default:
  423.             DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  424.                          prop_name));
  425.             return HXR_PROP_TYPE_MISMATCH;
  426.     }
  427.     // dispatch the callbacks and then return HXR_OK
  428.     return SetDone(d, p);
  429. }
  430. /*
  431.  *  Function Name:   SetInt
  432.  *  Input Params:    const UINT32 hash_key, const INT32 value
  433.  *  Return Value:    HX_RESULT
  434.  *  Description:
  435.  *   set a new value of the INTEGER property using the HashTree.
  436.  */
  437. HX_RESULT
  438. CommonRegistry::SetInt(const UINT32 hash_key, const INT32 value)
  439. {
  440.     DPRINTF(D_REGISTRY, ("CommonRegistry::SetInt(%lu, %ld)n", hash_key,
  441.                          value));
  442.     DB_node*  d = 0;
  443.     Property* p = 0;
  444.     d = (DB_node *)_ids->get(hash_key);
  445.     if (!d)
  446.     {
  447. DPRINTF(D_REGISTRY, ("SetInt(%lu) failedn", hash_key));
  448. return HXR_FAIL;
  449.     }
  450.     p = d->get_data();
  451.     if (!p)
  452.         return HXR_FAIL;
  453.     if (p->is_read_only())
  454.     {
  455.         DPRINTF(D_REGISTRY, ("%s(%lu) -- Property is READ ONLYn",
  456.                      p->get_key_str(), hash_key));
  457. return HXR_FAIL;
  458.     }
  459.     switch(p->get_type())
  460.     {
  461.         case PT_INTEGER:
  462.             p->int_val(value);
  463.             break;
  464.         case PT_INTREF:
  465.             DPRINTF(D_REGISTRY, ("cannot set INTREF value using SetIntn"));
  466.             return HXR_FAIL;
  467.         default:
  468.             DPRINTF(D_REGISTRY, ("%s(%lu) -- Property<-->Type MISMATCHn",
  469.                          p->get_key_str(), hash_key));
  470.             return HXR_PROP_TYPE_MISMATCH;
  471.     }
  472.     // dispatch the callbacks and then return HXR_OK
  473.     return SetDone(d, p);
  474. }
  475. /*
  476.  *  Function Name:   CommonRegistry::AddStr
  477.  *  Input Params:    const char* prop_name, const char* const value,
  478.  *  Return Value:    UINT32
  479.  *  Description:
  480.  *   adds a STRING Property ot the registry.
  481.  */
  482. UINT32
  483. CommonRegistry::AddStr(const char* prop_name, IHXBuffer* buf)
  484. {
  485.     DPRINTF(D_REGISTRY, ("CommonRegistry::AddStr(%s, buf(%p)n",
  486.                          prop_name, buf));
  487.     DB_node* d = 0;
  488.     Property* p = 0;
  489.     Key* k = new Key(prop_name);
  490.     if(!k)
  491.     {
  492.         return 0;
  493.     }
  494.     int len = k->size();
  495.     char* curr_key_str = new char[len];
  496.     if(!curr_key_str)
  497.     {
  498.         HX_DELETE(k);
  499.         return 0;
  500.     }
  501.     DB_implem* ldb = _logdb_imp;
  502.     BOOL read_only = FALSE;
  503.     *curr_key_str = '';
  504.     while(!k->last_sub_str())
  505.     {
  506.         k->append_sub_str(curr_key_str, len);
  507. if (p && p->get_type() == PT_COMPOSITE)
  508.     p->get_db_val(&ldb);
  509. if (!ldb)
  510. {
  511.     DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!n",
  512.             prop_name, curr_key_str));
  513.     delete k;
  514.     HX_VECTOR_DELETE(curr_key_str);
  515.     return 0;
  516. }
  517. d = ldb->find(curr_key_str);
  518. if (!d)
  519. {
  520.     int ret = _buildSubstructure4Prop(curr_key_str,
  521. prop_name);
  522.     if (!ret)
  523.     {
  524. delete k;
  525. delete[] curr_key_str;
  526. return 0;
  527.     }
  528.     d = ldb->find(curr_key_str);
  529.     if (!d)
  530.     {
  531. delete k;
  532. delete[] curr_key_str;
  533. return 0;
  534.     }
  535. }
  536. p = d->get_data();
  537.         if (!p)
  538. {
  539.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  540.                          prop_name, curr_key_str));
  541.     delete k;
  542.     HX_VECTOR_DELETE(curr_key_str);
  543.     return 0;
  544. }
  545. read_only = p->is_read_only();
  546. if (read_only)
  547. {
  548.     DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLYn",
  549.                          prop_name, curr_key_str));
  550.     delete k;
  551.     HX_VECTOR_DELETE(curr_key_str);
  552.     return 0;
  553. }
  554.     }
  555.     if (p && p->get_type() == PT_COMPOSITE)
  556. p->get_db_val(&ldb);
  557.     k->append_sub_str(curr_key_str, len);
  558.     if (ldb->find(curr_key_str))
  559.     {
  560. DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!n", k->get_key_str()));
  561. delete k;
  562. HX_VECTOR_DELETE(curr_key_str);
  563. return 0;
  564.     }
  565.     // everything is alright add the new property
  566.     DB_node* new_d = _addBuf(k, curr_key_str, buf, ldb, PT_STRING);
  567.     HX_VECTOR_DELETE(curr_key_str);
  568.     AddDone(ldb, new_d, d, p);
  569.     return new_d->get_id();
  570. }
  571. /*
  572.  *  Function Name:   GetStr
  573.  *  Input Params:    const char* prop_name, char*& value
  574.  *  Return Value:    HX_RESULT
  575.  *  Description:
  576.  *   retrieves a STRING Property value from the registry given its
  577.  *  property name.
  578.  */
  579. HX_RESULT
  580. CommonRegistry::GetStr(const char* prop_name, REF(IHXBuffer*) p_buf) const
  581. {
  582.     DB_node*  d = 0;
  583.     Property* p = 0;
  584.     if (_find(&d, &p, prop_name) != HXR_OK)
  585. return HXR_FAIL;
  586.     if (p)
  587.     {
  588. switch(p->get_type())
  589. {
  590.     case PT_STRING:
  591. return p->get_buf_val(&p_buf, PT_STRING);
  592. break;
  593.     default:
  594. DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  595.                      prop_name));
  596. return HXR_PROP_TYPE_MISMATCH;
  597. }
  598.     }
  599.     return HXR_FAIL;
  600. }
  601. /*
  602.  *  Function Name:   GetStr
  603.  *  Input Params:    const UINT32 hash_key, char*& value
  604.  *  Return Value:    HX_RESULT
  605.  *  Description:
  606.  *   retrieves a STRING Property value from the registry given its
  607.  *  hash key.
  608.  */
  609. HX_RESULT
  610. CommonRegistry::GetStr(const UINT32 hash_key, REF(IHXBuffer*) p_buf) const
  611. {
  612.     DB_node*  d = 0;
  613.     Property* p = 0;
  614.     d = (DB_node *)_ids->get(hash_key);
  615.     if (!d)
  616.     {
  617. DPRINTF(D_REGISTRY, ("GetStr(%lu) failedn", hash_key));
  618. return HXR_FAIL;
  619.     }
  620.     p = d->get_data();
  621.     if (p)
  622.     {
  623. switch(p->get_type())
  624. {
  625.     case PT_STRING:
  626. return p->get_buf_val(&p_buf, PT_STRING);
  627. break;
  628.     default:
  629. DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  630.                      hash_key));
  631. return HXR_PROP_TYPE_MISMATCH;
  632. }
  633.     }
  634.     return HXR_FAIL;
  635. }
  636. /*
  637.  *  Function Name:   SetStr
  638.  *  Input Params:    const char* prop_name, const IHXBuffer* value,
  639.  *                      size_t val_len
  640.  *  Return Value:    HX_RESULT
  641.  *  Description:
  642.  *   set the value of a STRING Property given a new value and its
  643.  *  CORRECT length.
  644.  */
  645. HX_RESULT
  646. CommonRegistry::SetStr(const char* prop_name, IHXBuffer* p_buf)
  647. {
  648.     DB_node*  d = 0;
  649.     Property* p = 0;
  650.     if (_find(&d, &p, prop_name) != HXR_OK)
  651. return HXR_FAIL;
  652.     if (!p)
  653.         return HXR_FAIL;
  654.     if (p->is_read_only())
  655.     {
  656.         DPRINTF(D_REGISTRY, ("%s -- Property is READ ONLYn",
  657.                      prop_name));
  658. return HXR_FAIL;
  659.     }
  660.     switch(p->get_type())
  661.     {
  662.         case PT_STRING:
  663.             p->buf_val(p_buf, PT_STRING);
  664.             break;
  665.         default:
  666.             DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  667.                          prop_name));
  668.             return HXR_PROP_TYPE_MISMATCH;
  669.     }
  670.     // dispatch the callbacks and then return HXR_OK
  671.     return SetDone(d, p);
  672. }
  673. /*
  674.  *  Function Name:   SetStr
  675.  *  Input Params:    const UINT32 hash_key, const IHXBuffer* value,
  676.  *                      size_t val_len
  677.  *  Return Value:    HX_RESULT
  678.  *  Description:
  679.  *   set the value of a STRING Property given a new value and its
  680.  *  CORRECT length.
  681.  */
  682. HX_RESULT
  683. CommonRegistry::SetStr(const UINT32 hash_key, IHXBuffer* p_buf)
  684. {
  685.     DB_node*  d = 0;
  686.     Property* p = 0;
  687.     UINT32    h = hash_key;
  688.     d = (DB_node *)_ids->get(hash_key);
  689.     if (!d)
  690.     {
  691. DPRINTF(D_REGISTRY, ("SetStr(%lu) failedn", hash_key));
  692. return HXR_FAIL;
  693.     }
  694.     p = d->get_data();
  695.     if (!p)
  696.         return HXR_FAIL;
  697.     if (p->is_read_only())
  698.     {
  699.         DPRINTF(D_REGISTRY, ("%lu -- Property is READ ONLYn",
  700.                      hash_key));
  701. return HXR_FAIL;
  702.     }
  703.     switch(p->get_type())
  704.     {
  705.         case PT_STRING:
  706.             p->buf_val(p_buf, PT_STRING);
  707.             break;
  708.         default:
  709.             DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  710.                          hash_key));
  711.             return HXR_PROP_TYPE_MISMATCH;
  712.     }
  713.     // dispatch the callbacks and then return HXR_OK
  714.     return SetDone(d, p);
  715. }
  716. UINT32
  717. CommonRegistry::AddBuf(const char* prop_name, IHXBuffer* buf)
  718. {
  719.     DPRINTF(D_REGISTRY, ("CommonRegistry::AddBuf(%s, buf(%p)n",
  720.                          prop_name, buf));
  721.     DB_node* d = 0;
  722.     Property* p = 0;
  723.     Key* k = new Key(prop_name);
  724.     if(!k)
  725.     {
  726.         return 0;
  727.     }
  728.     int len = k->size();
  729.     char* curr_key_str = new char[len];
  730.     if(!curr_key_str)
  731.     {
  732.         HX_DELETE(k);
  733.         return 0;
  734.     }
  735.     DB_implem* ldb = _logdb_imp;
  736.     BOOL read_only = FALSE;
  737.     *curr_key_str = '';
  738.     while(!k->last_sub_str())
  739.     {
  740.         k->append_sub_str(curr_key_str, len);
  741. if (p && p->get_type() == PT_COMPOSITE)
  742.     p->get_db_val(&ldb);
  743. if (!ldb)
  744. {
  745.     DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!n",
  746.                          prop_name, curr_key_str));
  747.     HX_VECTOR_DELETE(curr_key_str);
  748.     delete k;
  749.     return 0;
  750. }
  751. d = ldb->find(curr_key_str);
  752. if (!d)
  753. {
  754.     int ret = _buildSubstructure4Prop(curr_key_str,
  755. prop_name);
  756.     if (!ret)
  757.     {
  758. delete k;
  759. delete[] curr_key_str;
  760. return 0;
  761.     }
  762.     d = ldb->find(curr_key_str);
  763.     if (!d)
  764.     {
  765. delete k;
  766. delete[] curr_key_str;
  767. return 0;
  768.     }
  769. }
  770. p = d->get_data();
  771.         if (!p)
  772. {
  773.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  774.                          prop_name, curr_key_str));
  775.     HX_VECTOR_DELETE(curr_key_str);
  776.     delete k;
  777.     return 0;
  778. }
  779. read_only = p->is_read_only();
  780. if (read_only)
  781. {
  782.     DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLYn",
  783.                          prop_name, curr_key_str));
  784.     HX_VECTOR_DELETE(curr_key_str);
  785.     delete k;
  786.     return 0;
  787. }
  788.     }
  789.     if (p && p->get_type() == PT_COMPOSITE)
  790. p->get_db_val(&ldb);
  791.     k->append_sub_str(curr_key_str, len);
  792.     if (ldb->find(curr_key_str))
  793.     {
  794. DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!n", k->get_key_str()));
  795. HX_VECTOR_DELETE(curr_key_str);
  796. delete k;
  797. return 0;
  798.     }
  799.     // everything is alright add the new property
  800.     DB_node* new_d = _addBuf(k, curr_key_str, buf, ldb);
  801.     HX_VECTOR_DELETE(curr_key_str);
  802.     AddDone(ldb, new_d, d, p);
  803.     return new_d->get_id();
  804. }
  805. HX_RESULT
  806. CommonRegistry::GetBuf(const char* prop_name, IHXBuffer** pp_val) const
  807. {
  808.     DB_node*  d = 0;
  809.     Property* p = 0;
  810.     if (_find(&d, &p, prop_name) != HXR_OK)
  811. return HXR_FAIL;
  812.     if (p)
  813.     {
  814. if (p->get_type() == PT_BUFFER)
  815. {
  816.     return p->get_buf_val(pp_val);
  817. }
  818. else if (p->_alternate_string_access_ok)
  819. {
  820.     return p->get_buf_val(pp_val, PT_STRING);
  821. }
  822. else
  823. {
  824.     DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  825.  prop_name));
  826.     return HXR_PROP_TYPE_MISMATCH;
  827. }
  828.     }
  829.     return HXR_FAIL;
  830. }
  831. HX_RESULT
  832. CommonRegistry::GetBuf(const UINT32 hash_key, IHXBuffer** pp_buf) const
  833. {
  834.     DB_node*  d = 0;
  835.     Property* p = 0;
  836.     d = (DB_node *)_ids->get(hash_key);
  837.     if (!d)
  838.     {
  839. DPRINTF(D_REGISTRY, ("GetBuf(%lu) failedn", hash_key));
  840. return HXR_FAIL;
  841.     }
  842.     p = d->get_data();
  843.     if (p)
  844.     {
  845. if (p->get_type() == PT_BUFFER)
  846. {
  847.     return p->get_buf_val(pp_buf);
  848. }
  849. else if (p->_alternate_string_access_ok)
  850. {
  851.     return p->get_buf_val(pp_buf, PT_STRING);
  852. }
  853. else
  854. {
  855.     DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  856.  hash_key));
  857.     return HXR_PROP_TYPE_MISMATCH;
  858. }
  859.     }
  860.     return HXR_FAIL;
  861. }
  862. HX_RESULT
  863. CommonRegistry::SetBuf(const char* prop_name, IHXBuffer* p_buf)
  864. {
  865.     DB_node*  d = 0;
  866.     Property* p = 0;
  867.     if (_find(&d, &p, prop_name) != HXR_OK)
  868. return HXR_FAIL;
  869.     if (!p)
  870.         return HXR_FAIL;
  871.     if (p->is_read_only())
  872.     {
  873.         DPRINTF(D_REGISTRY, ("%s -- Property is READ ONLYn",
  874.                      prop_name));
  875. return HXR_FAIL;
  876.     }
  877.     if (p->get_type() == PT_BUFFER)
  878.     {
  879. p->buf_val(p_buf);
  880.     }
  881.     else if (p->_alternate_string_access_ok)
  882.     {
  883. p->buf_val(p_buf, PT_STRING);
  884.     }
  885.     else
  886.     {
  887. DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCHn",
  888.      prop_name));
  889. return HXR_PROP_TYPE_MISMATCH;
  890.     }
  891.     // dispatch the callbacks and then return HXR_OK
  892.     return SetDone(d, p);
  893. }
  894. HX_RESULT
  895. CommonRegistry::SetBuf(const UINT32 hash_key, IHXBuffer* p_buf)
  896. {
  897.     DB_node*  d = 0;
  898.     Property* p = 0;
  899.     UINT32    h = hash_key;
  900.     d = (DB_node *)_ids->get(hash_key);
  901.     if (!d)
  902.     {
  903. DPRINTF(D_REGISTRY, ("GetBuf(%lu) failedn", hash_key));
  904. return HXR_FAIL;
  905.     }
  906.     p = d->get_data();
  907.     if (!p)
  908.         return HXR_FAIL;
  909.     if (p->is_read_only())
  910.     {
  911.         DPRINTF(D_REGISTRY, ("%lu -- Property is READ ONLYn",
  912.                      hash_key));
  913. return HXR_FAIL;
  914.     }
  915.     switch(p->get_type())
  916.     {
  917.         case PT_BUFFER:
  918.     p_buf->AddRef();
  919.             p->buf_val(p_buf);
  920.     p_buf->Release();
  921.             break;
  922.         default:
  923.             DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  924.                          hash_key));
  925.             return HXR_PROP_TYPE_MISMATCH;
  926.     }
  927.     // dispatch the callbacks and then return HXR_OK
  928.     return SetDone(d, p);
  929. }
  930. HX_RESULT
  931. CommonRegistry::SetReadOnly(const char* pName, BOOL bValue)
  932. {
  933.     DB_node*  d = 0;
  934.     Property* p = 0;
  935.     if (_find(&d, &p, pName) != HXR_OK)
  936. return HXR_FAIL;
  937.     if (!p)
  938.         return HXR_FAIL;
  939.     _setReadOnly(p, bValue);
  940.     return HXR_OK;
  941. }
  942. HX_RESULT
  943. CommonRegistry::SetReadOnly(UINT32 ulRegId, BOOL bValue)
  944. {
  945.     DB_node*  d = 0;
  946.     Property* p = 0;
  947.     d = (DB_node *)_ids->get(ulRegId);
  948.     if (!d)
  949.     {
  950. DPRINTF(D_REGISTRY, ("SetReadOnly(%lu) failedn", ulRegId));
  951. return HXR_FAIL;
  952.     }
  953.     p = d->get_data();
  954.     if (!p)
  955.         return HXR_FAIL;
  956.     _setReadOnly(p, bValue);
  957.     return HXR_OK;
  958. }
  959. UINT32
  960. CommonRegistry::AddIntRef(const char* prop_name, INT32* val)
  961. {
  962.     DPRINTF(D_REGISTRY, ("CommonRegistry::AddIntRef(%s, %ld)n", prop_name,
  963.                          *val));
  964.     DB_node* d = 0;
  965.     Property* p = 0;
  966.     Key* k = new Key(prop_name);
  967.     if(!k)
  968.     {
  969.         return 0;
  970.     }
  971.     int len = k->size();
  972.     char* curr_key_str = new char[len];
  973.     if(!curr_key_str)
  974.     {
  975.         HX_DELETE(k);
  976.         return 0;
  977.     }
  978.     DB_implem* ldb = _logdb_imp;
  979.     BOOL read_only = FALSE;
  980.     *curr_key_str = '';
  981.     while(!k->last_sub_str())
  982.     {
  983.         k->append_sub_str(curr_key_str, len);
  984. if (p && p->get_type() == PT_COMPOSITE)
  985.     p->get_db_val(&ldb);
  986. if (!ldb)
  987. {
  988.     DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!n",
  989.                          prop_name, curr_key_str));
  990.     HX_VECTOR_DELETE(curr_key_str);
  991.     return 0;
  992. }
  993. d = ldb->find(curr_key_str);
  994. if (!d)
  995. {
  996.     DPRINTF(D_REGISTRY, ("%s -- %s was NOT FOUNDn",
  997.                          prop_name, curr_key_str));
  998.     HX_VECTOR_DELETE(curr_key_str);
  999.     return 0;
  1000. }
  1001. p = d->get_data();
  1002.         if (!p)
  1003. {
  1004.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  1005.                          prop_name, curr_key_str));
  1006.     HX_VECTOR_DELETE(curr_key_str);
  1007.     return 0;
  1008. }
  1009. read_only = p->is_read_only();
  1010. if (read_only)
  1011. {
  1012.     DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLYn",
  1013.                          prop_name, curr_key_str));
  1014.     HX_VECTOR_DELETE(curr_key_str);
  1015.     return 0;
  1016. }
  1017.     }
  1018.     if (p && p->get_type() == PT_COMPOSITE)
  1019. p->get_db_val(&ldb);
  1020.     k->append_sub_str(curr_key_str, len);
  1021.     if (ldb->find(curr_key_str))
  1022.     {
  1023. DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!n", k->get_key_str()));
  1024. HX_VECTOR_DELETE(curr_key_str);
  1025. return 0;
  1026.     }
  1027.     // everything is alright add the new property
  1028.     DB_node* new_d = _addIntRef(k, curr_key_str, val, ldb);
  1029.     HX_VECTOR_DELETE(curr_key_str);
  1030.     AddDone(ldb, new_d, d, p);
  1031.     return new_d->get_id();
  1032. }
  1033. /*
  1034.  *  Function Name:   Del
  1035.  *  Input Params:    const char* prop_name
  1036.  *  Return Value:    UINT32
  1037.  *  Description:
  1038.  *   delete a property (DB_node too) from the database given
  1039.  *  the key string.
  1040.  */
  1041. UINT32
  1042. CommonRegistry::Del(const char* prop_name)
  1043. {
  1044.     DB_node* d = 0;
  1045.     Property* p = 0;
  1046.     DB_implem* ldb = 0;
  1047.     if (_find(&d, &p, prop_name) != HXR_OK)
  1048. return 0;
  1049.     if (!p)
  1050.     {
  1051. DPRINTF(D_REGISTRY, ("%s -- has NO DATAn", prop_name));
  1052.         return 0;
  1053.     }
  1054.     // XXXDPS - Currently we do not check if any of the children are read-
  1055.     // only before deleting the key. Thus, a user could delete a read-only
  1056.     // node by deleting its parent, grandparent, etc. This would slow down
  1057.     // the Del() call significantly in the general case because we would
  1058.     // have to do a search first, and abort the entire operation if any child
  1059.     // is read-only. So it is currently safest to write-protect a key that
  1060.     // has no parents (a root key, like "license" or "config").
  1061.     if (p->is_read_only())
  1062.     {
  1063. DPRINTF(D_REGISTRY, ("%s -- is READ ONLYn", prop_name));
  1064.         return 0;
  1065.     }
  1066.     // find the DB that contains this node
  1067.     ldb = d->get_db();
  1068.     if (!ldb)
  1069.     {
  1070. DPRINTF(D_REGISTRY, ("%s -- has NO IMPLEMENTATIONn", prop_name));
  1071.         return 0;
  1072.     }
  1073.     // here the response method doesn't exactly end this method
  1074.     DeleteDone(ldb, d, p);
  1075.     UINT32 h = d->get_id();
  1076.     if (p->m_lWatchCount)
  1077.     {
  1078. /*
  1079.  * Wait for the clear watches to delete the node
  1080.  */
  1081. p->set_deleted(ldb, d, h);
  1082. return h;
  1083.     }
  1084.     return _Del(ldb, d, p, h);
  1085. }
  1086. /*
  1087.  *  Function Name:   Del
  1088.  *  Input Params:    const UINT32 hash_key
  1089.  *  Return Value:    UINT32
  1090.  *  Description:
  1091.  *   delete a property (DB_node too) from the database given
  1092.  *  the key string.
  1093.  */
  1094. UINT32
  1095. CommonRegistry::Del(const UINT32 hash_key)
  1096. {
  1097.     DB_node* d = 0;
  1098.     Property* p = 0;
  1099.     DB_implem* ldb = _logdb_imp;
  1100.     d = (DB_node *)_ids->get(hash_key);
  1101.     if (!d)
  1102.     {
  1103. DPRINTF(D_REGISTRY, ("%lu -- was NOT FOUNDn", hash_key));
  1104. return 0;
  1105.     }
  1106.     p = d->get_data();
  1107.     if (!p)
  1108.     {
  1109. DPRINTF(D_REGISTRY, ("%lu -- has NO DATAn", hash_key));
  1110. return 0;
  1111.     }
  1112.     if (p->is_read_only())
  1113.     {
  1114. DPRINTF(D_REGISTRY, ("%lu -- is READ ONLYn", hash_key));
  1115.         return 0;
  1116.     }
  1117.     // find the DB that contains this node
  1118.     ldb = d->get_db();
  1119.     if (!ldb)
  1120.     {
  1121. DPRINTF(D_REGISTRY, ("%lu -- has NO IMPLEMENTATIONn", hash_key));
  1122.         return 0;
  1123.     }
  1124.     // here the response method doesn't exactly end this method
  1125.     DeleteDone(ldb, d, p);
  1126.     if (p->m_lWatchCount)
  1127.     {
  1128. /*
  1129.  * Wait for the clear watches to delete the node
  1130.  */
  1131. p->set_deleted(ldb, d, hash_key);
  1132. return hash_key;
  1133.     }
  1134.     return _Del(ldb, d, p, hash_key);
  1135. }
  1136. UINT32
  1137. CommonRegistry::_Del(DB_implem* ldb, DB_node* d, Property* p, UINT32 h)
  1138. {
  1139.     if (p->get_type() == PT_COMPOSITE)
  1140.     {
  1141. DB_implem* temp_ldb;
  1142. p->get_db_val(&temp_ldb);
  1143. if (_del(temp_ldb) == HXR_FAIL)
  1144.     return 0;
  1145.     }
  1146.     _ids->destroy(h);
  1147.     ldb->del(d);
  1148.     _count--;
  1149.     return h;
  1150. }
  1151. UINT32
  1152. CommonRegistry::SetWatch(PropWatch* pPropWatch)
  1153. {
  1154.     /*
  1155.      * XXXAAK -- need to do some checking to disallow duplicate watchpoints
  1156.      * per process
  1157.      */
  1158.     WListElem* wle = new WListElem;
  1159.     wle->data = pPropWatch;
  1160.     m_pWatchList->insert(wle);
  1161.     m_lWatchCount++;
  1162.     return 1;
  1163. }
  1164. UINT32
  1165. CommonRegistry::SetWatch(const char* prop_name, PropWatch* pPropWatch)
  1166. {
  1167.     DB_node*  d = 0;
  1168.     Property* p = 0;
  1169.     if (_find(&d, &p, prop_name) == HXR_OK)
  1170.     {
  1171. WListElem* wle = new WListElem;
  1172. wle->data = pPropWatch;
  1173. p->m_pWatchList->insert(wle);
  1174. p->m_lWatchCount++;
  1175. return d->get_id();
  1176.     }
  1177.     return 0;
  1178. }
  1179. UINT32
  1180. CommonRegistry::SetWatch(const UINT32 hash_key, PropWatch* pPropWatch)
  1181. {
  1182.     DB_node*  d = 0;
  1183.     Property* p = 0;
  1184.     d = (DB_node *)_ids->get(hash_key);
  1185.     if (!d)
  1186. return 0;
  1187.     p = (Property *)d->get_data();
  1188.     if (p)
  1189.     {
  1190. WListElem* wle = new WListElem;
  1191. wle->data = pPropWatch;
  1192. p->m_pWatchList->insert(wle);
  1193. p->m_lWatchCount++;
  1194. return hash_key;
  1195.     }
  1196.     return 0;
  1197. }
  1198. /*
  1199.  *  Function Name:   SetTrickleWatch
  1200.  *  Input Params:    const char* par_prop_name, const char* target_name,
  1201.  *                      PropWatch* cb
  1202.  *  Return Value:    UINT32
  1203.  *  Description:
  1204.  *   this method does kinda a watch for a Property that will be added
  1205.  *  in the future. when the "target_name" Property gets added somewhere
  1206.  *  under the hierarchy of the parent Property "par_prop_name" the watch
  1207.  *  will be TRICKLED down the hierarchy until it reaches its target and
  1208.  *  set it for the target. if the target never gets added the callback
  1209.  *  will NOT be triggered.
  1210.  */
  1211. HX_RESULT
  1212. CommonRegistry::SetTrickleWatch(const char* par_prop_name, 
  1213.                                 const char* target_name,
  1214.         PropWatch* cb)
  1215. {
  1216.     // not supported!!!
  1217.     return HXR_NOTIMPL; 
  1218. }
  1219. /*
  1220.  *  Function Name:   CommonRegistry::ClearWatch
  1221.  *  Input Params:    int proc_num
  1222.  *  Return Value:    HX_RESULT
  1223.  *  Description:
  1224.  *   clear a watchpoint from the global watchlist at the highgest 
  1225.  *  level of the database hierarchy.
  1226.  */
  1227. HX_RESULT
  1228. CommonRegistry::ClearWatch(IHXPropWatchResponse* pResonse)
  1229. {
  1230.     return _clearWatch(pResonse);
  1231. }
  1232. HX_RESULT
  1233. CommonRegistry::ClearWatch(const char* prop_name, IHXPropWatchResponse* pResonse)
  1234. {
  1235.     DB_node*  d = 0;
  1236.     Property* p = 0;
  1237.     if (_find(&d, &p, prop_name) != HXR_OK)
  1238. return HXR_FAIL;
  1239.     return _clearWatch(p, pResonse);
  1240. }
  1241. HX_RESULT
  1242. CommonRegistry::ClearWatch(const UINT32 hash_key, IHXPropWatchResponse* pResonse)
  1243. {
  1244.     DB_node*  d = 0;
  1245.     Property* p = 0;
  1246.     d = (DB_node *)_ids->get(hash_key);
  1247.     if (!d)
  1248.     {
  1249. return HXR_FAIL;
  1250.     }
  1251.     p = d->get_data();
  1252.     return _clearWatch(p, pResonse);
  1253. }
  1254. HX_RESULT
  1255. CommonRegistry::AddDone(DB_implem* db_level, DB_node* new_node,
  1256.                 DB_node* parent_node, Property* parent_prop)
  1257. {
  1258.     _dispatchParentCallbacks(db_level, new_node, DBE_ADDED);
  1259.     
  1260.     return HXR_OK;
  1261. }
  1262. HX_RESULT
  1263. CommonRegistry::SetDone(DB_node* new_node, Property* new_prop)
  1264. {
  1265.     _dispatchCallbacks(new_node, new_prop, DBE_MODIFIED);
  1266.     return HXR_OK;
  1267. }
  1268. HX_RESULT
  1269. CommonRegistry::DeleteDone(DB_implem* db_level, DB_node* node,
  1270.    Property* prop)
  1271. {
  1272.     _dispatchCallbacks(node, prop, DBE_DELETED);
  1273.     _dispatchParentCallbacks(db_level, node, DBE_DELETED);
  1274.    
  1275.     return HXR_OK;
  1276. }
  1277. DB_node*
  1278. CommonRegistry::_addComp(Key* k, char* key_str, DB_implem* ldb)
  1279. {
  1280.     DPRINTF(D_REGISTRY, ("CommonRegistry::_addComp()n"));
  1281.     Property* new_p = new Property(k, PT_COMPOSITE);
  1282.     if( !new_p )
  1283.     {
  1284.         return NULL;
  1285.     }
  1286.     DB_node* new_d = ldb->add(key_str, new_p);
  1287.     if( !new_d )
  1288.     {
  1289. delete new_p;
  1290. return NULL;
  1291.     }
  1292.     DB_dict* pNewDb = new DB_dict(new_d);
  1293.     if( !pNewDb )
  1294.     {
  1295. delete new_p;
  1296. delete new_d;
  1297. return NULL;
  1298.     }
  1299.     new_p->db_val(pNewDb);
  1300.     UINT32 id = _ids->create((void *)new_d);
  1301.     new_d->id(id);
  1302.     _count++;
  1303.     return new_d;
  1304. }
  1305. DB_node*
  1306. CommonRegistry::_addInt(Key* k, char* key_str, INT32 val, DB_implem* ldb)
  1307. {
  1308.     DPRINTF(D_REGISTRY, ("CommonRegistry::_addInt()n"));
  1309.     Property* new_p = new Property(k, PT_INTEGER);
  1310.     if(!new_p)
  1311.     {
  1312.         return NULL;
  1313.     }
  1314.     new_p->int_val(val);
  1315.     DB_node* new_d = ldb->add(key_str, new_p);
  1316.     if (!new_d)
  1317.     {
  1318. delete new_p;
  1319. return 0;
  1320.     }
  1321.     UINT32 id = _ids->create((void *)new_d);
  1322.     new_d->id(id);
  1323.     _count++;
  1324.     return new_d;
  1325. }
  1326. DB_node*
  1327. CommonRegistry::_addBuf(Key* k, char* key_str, IHXBuffer* buf, DB_implem* ldb,
  1328.                         HXPropType val_type)
  1329. {
  1330.     DPRINTF(D_REGISTRY, ("CommonRegistry::_addBuf()n"));
  1331.     Property* new_p = new Property(k, val_type);
  1332.     if(!new_p)
  1333.     {
  1334.         return NULL;
  1335.     }
  1336.     // AddRef gets called within the buf_val() method
  1337.     new_p->buf_val(buf, val_type);
  1338.     DB_node* new_d = ldb->add(key_str, new_p);
  1339.     if (!new_d)
  1340.     {
  1341. delete new_p;
  1342. return 0;
  1343.     }
  1344.     UINT32 id = _ids->create((void *)new_d);
  1345.     new_d->id(id);
  1346.     _count++;
  1347.     return new_d;
  1348. }
  1349. DB_node*
  1350. CommonRegistry::_addIntRef(Key* k, char* key_str, INT32* val, DB_implem* ldb)
  1351. {
  1352.     DPRINTF(D_REGISTRY, ("CommonRegistry::_addIntRef()n"));
  1353.     Property* new_p = new Property(k, PT_INTREF);
  1354.     new_p->int_ref_val(val);
  1355.     DB_node* new_d = ldb->add(key_str, new_p);
  1356.     if (!new_d)
  1357.     {
  1358. delete new_p;
  1359. return 0;
  1360.     }
  1361.     UINT32 id = _ids->create((void *)new_d);
  1362.     new_d->id(id);
  1363.     _count++;
  1364.     return new_d;
  1365. }
  1366. /*
  1367.  *  Function Name:   _dispatchParentCallbacks
  1368.  *  Input Params:    DB_implem* db, DB_node* currNode, DB_Event e
  1369.  *  Return Value:    void
  1370.  *  Description:
  1371.  *      fires off the callbacks of the Parent of the
  1372.  *  Property in "currNode". it is used only when a Property gets
  1373.  *  added or deleted.
  1374.  */
  1375. void
  1376. CommonRegistry::_dispatchParentCallbacks(DB_implem* db, DB_node* currNode, 
  1377.                                          DB_Event e)
  1378. {
  1379.     DB_node*     parNode = 0; // parent's node
  1380.     Property*     parProp = 0; // parent's property
  1381.     UINT32      par_hash_key = 0;
  1382.     if (_logdb_imp == db)
  1383.     {
  1384. if (!m_pWatchList || m_pWatchList->empty())
  1385.     return;
  1386. PropWatch*  pPropWatch = NULL;
  1387. UINT32 hash_key = currNode->get_id();
  1388. DPRINTF(D_REGISTRY, ("_dPC -- before root loopn"));
  1389. for (WatchList_iterator wli(m_pWatchList); *wli != 0; ++wli)
  1390. {
  1391.     WListElem* wle = *wli;
  1392.     pPropWatch = (PropWatch *)wle->data;
  1393.     switch (e)
  1394.     {
  1395.     case DBE_ADDED:
  1396. pPropWatch->m_pResponse->AddedProp(hash_key, PT_UNKNOWN, 0);
  1397. break;
  1398.     case DBE_MODIFIED:
  1399. pPropWatch->m_pResponse->ModifiedProp(hash_key, PT_UNKNOWN, 0);
  1400. break;
  1401.     case DBE_DELETED:
  1402. pPropWatch->m_pResponse->DeletedProp(hash_key, 0);
  1403. break;
  1404.     default:
  1405. break;
  1406.     }
  1407. }
  1408.     }
  1409.     else
  1410.     {
  1411. // find the node that owns this DB
  1412. parNode = db->owner_node();
  1413. if (parNode)
  1414. {
  1415.     par_hash_key = parNode->get_id();
  1416.     // get the parent's Property
  1417.     parProp = parNode->get_data();
  1418.     if (!parProp)
  1419.     {
  1420. DPRINTF(D_REGISTRY, ("%s has an INVALID parent Propertyn",
  1421.                      currNode->get_data()->get_key_str()));
  1422. return;
  1423.     }
  1424. }
  1425. else
  1426. {
  1427.     DPRINTF(D_REGISTRY, ("%s has an INVALID parent DB_noden",
  1428.                          currNode->get_data()->get_key_str()));
  1429.     return;
  1430. }
  1431. if (!parProp->m_pWatchList || parProp->m_pWatchList->empty())
  1432.     return;
  1433. UINT32 hash_key = currNode->get_id();
  1434. for (WatchList_iterator wli(parProp->m_pWatchList); *wli != 0; ++wli)
  1435. {
  1436.     WListElem* wle = *wli;
  1437.     PropWatch* pPropWatch = (PropWatch *)wle->data;
  1438.     switch (e)
  1439.     {
  1440.     case DBE_ADDED:
  1441. pPropWatch->m_pResponse->AddedProp(hash_key, PT_UNKNOWN, 
  1442.    par_hash_key);
  1443. break;
  1444.     case DBE_MODIFIED:
  1445. pPropWatch->m_pResponse->ModifiedProp(hash_key, PT_UNKNOWN,
  1446.       par_hash_key);
  1447. break;
  1448.     case DBE_DELETED:
  1449. pPropWatch->m_pResponse->DeletedProp(hash_key, par_hash_key);
  1450. break;
  1451.     default:
  1452. break;
  1453.     }
  1454. }
  1455.     }
  1456. }
  1457. /*
  1458.  *  Function Name:   _dispatchCallbacks
  1459.  *  Input Params:    UINT32 hash_key, Property* p, DB_Event e
  1460.  *  Return Value:    void
  1461.  *  Description:
  1462.  *   it fires off the watch callbacks of the Property "p" whenever
  1463.  *  it gets modified or deleted.
  1464.  */
  1465. void
  1466. CommonRegistry::_dispatchCallbacks(DB_node* d, Property* p, DB_Event e)
  1467. {
  1468.     if (p->m_lWatchCount <= 0)
  1469. return;
  1470.     UINT32 hash_key = d->get_id();
  1471.     UINT32 par_id = 0;
  1472.     // find the DB that contains this node
  1473.     DB_implem* ldb = d->get_db();
  1474.     if (ldb)
  1475.     {
  1476. // find the node that owns the DB
  1477. DB_node* par_node = ldb->owner_node();
  1478. if (par_node)
  1479.     par_id = par_node->get_id();
  1480.     }
  1481.     for (WatchList_iterator wli(p->m_pWatchList); *wli != 0; ++wli)
  1482.     {
  1483. WListElem* wle = *wli;
  1484. PropWatch* pPropWatch = (PropWatch *)wle->data;
  1485. switch (e)
  1486. {
  1487. case DBE_ADDED:
  1488.     pPropWatch->m_pResponse->AddedProp(hash_key, PT_UNKNOWN, par_id);
  1489.     break;
  1490. case DBE_MODIFIED:
  1491.     pPropWatch->m_pResponse->ModifiedProp(hash_key, PT_UNKNOWN, par_id);
  1492.     break;
  1493. case DBE_DELETED:
  1494.     pPropWatch->m_pResponse->DeletedProp(hash_key, par_id);
  1495.     break;
  1496. default:
  1497.     break;
  1498. }
  1499.     }
  1500. }
  1501. /*
  1502.  *  Function Name:   CommonRegistry::_clearWatch
  1503.  *  Input Params:    int proc_num
  1504.  *  Return Value:    HX_RESULT
  1505.  *  Description:
  1506.  *   clear watch at the root level of the registry.
  1507.  */
  1508. HX_RESULT
  1509. CommonRegistry::_clearWatch(IHXPropWatchResponse* pResonse)
  1510. {
  1511.     for (WatchList_iterator wli(m_pWatchList); *wli != 0; ++wli)
  1512.     {
  1513. WListElem* wle = *wli;
  1514. PropWatch* pPropWatch = (PropWatch *)wle->data;
  1515.     // Delete the entry that contains pResonse if one was supplied.
  1516.     // If pResponse is NULL, blindly delete the first entry in the watch list.
  1517.     if ((pPropWatch && pResonse && pPropWatch->m_pResponse == pResonse) ||
  1518.         !pResonse)
  1519.     {
  1520.         m_pWatchList->removeElem(wle);
  1521.     delete wle;
  1522.     delete pPropWatch;
  1523.     m_lWatchCount--;
  1524.     }
  1525.     }
  1526.     
  1527.     return HXR_OK;
  1528. }
  1529. /*
  1530.  *  Function Name:   _clearWatch
  1531.  *  Input Params:    Property* p
  1532.  *  Return Value:    HX_RESULT
  1533.  *  Description:
  1534.  *   clears a watch callback (watchpoint) from a Property based on 
  1535.  *  the process number. if the Property is not specified, then the
  1536.  *  watchpoints at the highgest level are cleared.
  1537.  */
  1538. HX_RESULT
  1539. CommonRegistry::_clearWatch(Property* p, IHXPropWatchResponse* pResonse)
  1540. {
  1541.     if (p)
  1542.     {
  1543. for (WatchList_iterator wli(p->m_pWatchList); *wli != 0; ++wli)
  1544. {
  1545.     WListElem* wle = *wli;
  1546.     PropWatch* pPropWatch = (PropWatch *)wle->data;
  1547.     
  1548.         // Delete the entry that contains pResonse if one was supplied.
  1549.         // If pResponse is NULL, blindly delete the first entry in the watch list.
  1550.         if ((pPropWatch && pResonse && pPropWatch->m_pResponse == pResonse) ||
  1551.             !pResonse)
  1552.         {
  1553.             delete pPropWatch;
  1554.         return DeleteWatch(p, wle);
  1555.         }
  1556. }
  1557.     }
  1558.     return HXR_OK;
  1559. }
  1560. HX_RESULT
  1561. CommonRegistry::DeleteWatch(Property* p, WListElem* wle)
  1562. {
  1563.     p->m_pWatchList->removeElem(wle);
  1564.     delete wle;
  1565.     p->m_lWatchCount--;
  1566.     if (p->is_deleted() && !p->m_lWatchCount)
  1567.     {
  1568. _Del(p->_owner_db, p->_owner_node, p, p->_id);
  1569.     }
  1570.     return HXR_OK;
  1571. }
  1572. /*
  1573.  *  Function Name:   GetType
  1574.  *  Input Params:    const char* prop_name
  1575.  *  Return Value:    HXPropType
  1576.  *  Description:
  1577.  *      returns the Datatype of the Property.
  1578.  */
  1579. HXPropType
  1580. CommonRegistry::GetType(const char* prop_name) const
  1581. {
  1582.     DB_node*  d = 0;
  1583.     Property* p = 0;
  1584.     if (_find(&d, &p, prop_name) == HXR_OK)
  1585. if (p)
  1586.     return p->get_type();
  1587.     return PT_UNKNOWN;
  1588. }
  1589. /*
  1590.  *  Function Name:   GetType
  1591.  *  Input Params:    const UINT32 hash_key
  1592.  *  Return Value:    HXPropType
  1593.  *  Description:
  1594.  *      returns the Datatype of the Property.
  1595.  */
  1596. HXPropType
  1597. CommonRegistry::GetType(const UINT32 hash_key) const
  1598. {
  1599.     DB_node*  d = 0;
  1600.     Property* p = 0;
  1601.     UINT32    h = hash_key;
  1602.     d = (DB_node *)_ids->get(hash_key);
  1603.     if (!d)
  1604.     {
  1605. DPRINTF(D_REGISTRY, ("Get Type (%lu) failedn", hash_key));
  1606. return PT_UNKNOWN;
  1607.     }
  1608.     p = d->get_data();
  1609.     if (p)
  1610. return p->get_type();
  1611.     return PT_UNKNOWN;
  1612. }
  1613. /*
  1614.  *  Function Name:   CommonRegistry::GetPropList const
  1615.  *  Input Params: IHXValues*& pValues
  1616.  *  Return Value:    HX_RESULT
  1617.  *  Description:
  1618.  *   it returns back a list of triples one for each property under 
  1619.  *  highest level of the database. each of these properties consists of 
  1620.  *  name, type and the hash key
  1621.  *
  1622.  *  XXXAAK -- return a list of hash keys if the list element is PT_COMPOSITE.
  1623.  */
  1624. HX_RESULT
  1625. CommonRegistry::GetPropList(IHXValues*& pValues) const
  1626. {
  1627.     return _getPropList(_logdb_imp, pValues);
  1628. }
  1629. /*
  1630.  *  Function Name:   CommonRegistry::GetPropList const
  1631.  *  Input Params:    const char* prop_name, IHXValues*& pValues
  1632.  *  Return Value:    HX_RESULT
  1633.  *  Description:
  1634.  *   given a PT_COMPOSITE property, it returns back a list of triples
  1635.  *  one for each property under the PT_COMPOSITE. each of which consists 
  1636.  *  of property name, type and the hash key
  1637.  *
  1638.  *  XXXAAK -- return a list of hash keys if the list element is PT_COMPOSITE.
  1639.  */
  1640. HX_RESULT
  1641. CommonRegistry::GetPropList(const char* prop_name, IHXValues*& pValues) const
  1642. {
  1643.     DB_node*  d = 0;
  1644.     Property* p = 0;
  1645.     if (_find(&d, &p, prop_name) == HXR_OK)
  1646.     {
  1647. if (p)
  1648. {
  1649.     switch(p->get_type())
  1650.     {
  1651. case PT_COMPOSITE:
  1652. {
  1653.     DB_implem* ldb = 0;
  1654.     p->get_db_val(&ldb);
  1655.     return _getPropList(ldb, pValues);
  1656. }
  1657. default:
  1658.     DPRINTF(D_REGISTRY, ("%s -- is NOT a COMPOSITE propertyn", 
  1659.                          prop_name));
  1660.     break;
  1661.     }
  1662. }
  1663.     }
  1664.     return HXR_FAIL;
  1665. }
  1666. HX_RESULT
  1667. CommonRegistry::Copy(const char* pFrom, const char* pTo)
  1668. {
  1669.     HXPropType type;
  1670.     type = GetType(pFrom);
  1671.     char buf[256]; /* Flawfinder: ignore */
  1672.     INT32 Int;
  1673.     UINT32 ul;
  1674.     IHXBuffer* pBuffer = 0;
  1675.     HX_RESULT res;
  1676.     IHXValues* pValues = 0;
  1677.     const char* pName;
  1678.     switch (type)
  1679.     {
  1680.     case PT_COMPOSITE:
  1681. /*
  1682.  * Get all props and recurse copy all of them.
  1683.  */
  1684. if (HXR_OK != (res = GetPropList(pFrom, pValues)))
  1685. {
  1686.     break;
  1687. }
  1688. if (HXR_OK == pValues->GetFirstPropertyULONG32(pName, ul))
  1689. {
  1690.     SafeStrCpy(buf, pTo, 256);
  1691.     SafeStrCat(buf, pName + strlen(pFrom), 256);
  1692.     res = Copy(pName, buf);
  1693.     while (HXR_OK == pValues->GetNextPropertyULONG32(pName, ul))
  1694.     {
  1695. SafeStrCpy(buf, pTo, 256);
  1696. SafeStrCat(buf, pName + strlen(pFrom), 256);
  1697. res = Copy(pName, buf);
  1698.     }
  1699. }
  1700. HX_RELEASE(pValues);
  1701. break;
  1702.     case PT_INTEGER:
  1703. if (HXR_OK != (res = GetInt(pFrom, &Int)))
  1704. {
  1705.     break;
  1706. }
  1707. if (AddInt(pTo, Int))
  1708. {
  1709.     res = HXR_OK;
  1710. }
  1711. else
  1712. {
  1713.     res = HXR_FAIL;
  1714. }
  1715. break;
  1716.     case PT_STRING:
  1717. if (HXR_OK != (res = GetStr(pFrom, pBuffer)))
  1718. {
  1719.     break;
  1720. }
  1721. if (AddStr(pTo, pBuffer))
  1722. {
  1723.     res = HXR_OK;
  1724. }
  1725. else
  1726. {
  1727.     res = HXR_FAIL;
  1728. }
  1729. if (pBuffer)
  1730. {
  1731.     pBuffer->Release();
  1732. }
  1733. pBuffer = 0;
  1734. break;
  1735.     case PT_BUFFER:
  1736. if (HXR_OK != (res = GetBuf(pFrom, &pBuffer)))
  1737. {
  1738.     break;
  1739. }
  1740. if (AddBuf(pTo, pBuffer))
  1741. {
  1742.     res = HXR_OK;
  1743. }
  1744. else
  1745. {
  1746.     res = HXR_FAIL;
  1747. }
  1748. if (pBuffer)
  1749. {
  1750.     pBuffer->Release();
  1751. }
  1752. pBuffer = 0;
  1753. break;
  1754.     
  1755.     default:
  1756. res = HXR_FAIL;
  1757.     }
  1758.     return res;
  1759. }
  1760. HX_RESULT
  1761. CommonRegistry::SetStringAccessAsBufferById(UINT32 hash_key)
  1762. {
  1763.     DB_node*  d = 0;
  1764.     Property* p = 0;
  1765.     d = (DB_node *)_ids->get(hash_key);
  1766.     if (!d)
  1767.     {
  1768. DPRINTF(D_REGISTRY, ("SetStringAccessAsBufferById(%lu) failedn",
  1769.     hash_key));
  1770. return HXR_FAIL;
  1771.     }
  1772.     p = d->get_data();
  1773.     if (p)
  1774.     {
  1775. switch(p->get_type())
  1776. {
  1777.     case PT_STRING:
  1778. p->SetStringAccessAsBufferById();
  1779. return HXR_OK;
  1780.     default:
  1781. DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCHn",
  1782.                      hash_key));
  1783. return HXR_PROP_TYPE_MISMATCH;
  1784. }
  1785.     }
  1786.     return HXR_FAIL;
  1787. }
  1788. /*
  1789.  *  Function Name:   CommonRegistry::GetPropList const
  1790.  *  Input Params:    const UINT32 hash_key, IHXValues*& pValues
  1791.  *  Return Value:    HX_RESULT
  1792.  *  Description:
  1793.  *   given a PT_COMPOSITE property, it returns back a list of triples
  1794.  *  one for each property under the PT_COMPOSITE. each of which consists 
  1795.  *  of property name, type and the hash key
  1796.  *
  1797.  *  XXXAAK -- return a list of hash keys if the list element is PT_COMPOSITE.
  1798.  */
  1799. HX_RESULT
  1800. CommonRegistry::GetPropList(const UINT32 hash_key, IHXValues*& pValues) const
  1801. {
  1802.     if (!hash_key)
  1803. return _getPropList(_logdb_imp, pValues);
  1804.     DB_node*  d = 0;
  1805.     Property* p = 0;
  1806.     d = (DB_node *)_ids->get(hash_key);
  1807.     if (!d)
  1808.     {
  1809. DPRINTF(D_REGISTRY, ("could not get PropList for %lu -- no datan",
  1810.                      hash_key));
  1811. return HXR_FAIL;
  1812.     }
  1813.     p = d->get_data();
  1814.     if (p)
  1815.     {
  1816. switch(p->get_type())
  1817. {
  1818.     case PT_COMPOSITE:
  1819.     {
  1820. DB_implem* ldb = 0;
  1821. p->get_db_val(&ldb);
  1822. return _getPropList(ldb, pValues);
  1823.     }
  1824.     default:
  1825. DPRINTF(D_REGISTRY, ("%s(%lu) -- is NOT a COMPOSITE propertyn",
  1826.                      p->get_key_str(), hash_key));
  1827. break;
  1828. }
  1829.     }
  1830.     return HXR_FAIL;
  1831. }
  1832. /*
  1833.  *  Function Name:   CommonRegistry::GetPropName const
  1834.  *  Input Params:    const UINT32 id, IHXBuffer*& prop_name
  1835.  *  Return Value:    HX_RESULT
  1836.  *  Description:
  1837.  *   return a pointer to the key string of the Property whose
  1838.  *  id is given.
  1839.  */
  1840. HX_RESULT
  1841. CommonRegistry::GetPropName(const UINT32 id, IHXBuffer*& prop_name) const
  1842. {
  1843.     DB_node* d = (DB_node *)_ids->get(id);
  1844.     if (d)
  1845.     {
  1846. Property* p = d->get_data();
  1847. if (p)
  1848. {
  1849.     prop_name = new CHXBuffer;
  1850.     prop_name->Set((const unsigned char *)p->get_key_str(), 
  1851.    p->get_key_str_len());
  1852.     prop_name->AddRef();
  1853.     return HXR_OK;
  1854. }
  1855.     }
  1856.     return HXR_FAIL;
  1857. }
  1858. /*
  1859.  *  Function Name:   GetId
  1860.  *  Input Params:    const char* prop_name
  1861.  *  Return Value:    UINT32
  1862.  *  Description:
  1863.  *   returns the ID value for the Property name (prop_name) passed
  1864.  *  as a parameter. the main CONDITION is that the Property MUST EXIST,
  1865.  *  otherwise it returns a ZERO (0).
  1866.  */
  1867. UINT32
  1868. CommonRegistry::GetId(const char* prop_name) const
  1869. {
  1870.     DPRINTF(D_REGISTRY&D_ENTRY, ("CommonRegistry::GetId(%s)n", prop_name));
  1871.     DB_node* d = 0;
  1872.     Property* p = 0;
  1873.     if (_find(&d, &p, prop_name) == HXR_OK)
  1874. if (d)
  1875.         return d->get_id();
  1876.     return 0;
  1877. }
  1878. UINT32
  1879. CommonRegistry::FindParentKey(const char* prop_name)
  1880. {
  1881.     DB_node* d = 0;
  1882.     Property* p = 0;
  1883.     if (_find(&d, &p, prop_name) == HXR_OK)
  1884.     {
  1885. if (d)
  1886. {
  1887.     // find the DB that contains this node
  1888.     DB_implem* ldb = d->get_db();
  1889.     if (ldb)
  1890.     {
  1891. // find the node that owns this DB
  1892. d = ldb->owner_node();
  1893. if (d)
  1894.     return d->get_id();
  1895.     }
  1896. }
  1897.     }
  1898.     return 0;
  1899. }
  1900. UINT32
  1901. CommonRegistry::FindParentKey(const UINT32 hash_key)
  1902. {
  1903.     DB_node* d = (DB_node *)_ids->get(hash_key);
  1904.     // find the node with the hash key
  1905.     if (d)
  1906.     {
  1907. // find the DB that contains this node
  1908. DB_implem* ldb = d->get_db();
  1909. if (ldb)
  1910. {
  1911.     // find the node that owns this DB
  1912.     d = ldb->owner_node();
  1913.     if (d)
  1914. return d->get_id();
  1915. }
  1916.     }
  1917.     return 0;
  1918. }
  1919. /*
  1920.  *  Function Name:   CommonRegistry::Count const
  1921.  *  Input Params:   
  1922.  *  Return Value:    INT32
  1923.  *  Description:
  1924.  *   returns the total number of Properties (including COMPOSITE types)
  1925.  *  in the registry.
  1926.  */
  1927. INT32
  1928. CommonRegistry::Count() const
  1929. {
  1930.     return _count;
  1931. }
  1932. /*
  1933.  *  Function Name:   CommonRegistry::Count
  1934.  *  Input Params:    const char* prop_name
  1935.  *  Return Value:    UINT32
  1936.  *  Description:
  1937.  *   returns the number of Properties below the COMPOSITE whose
  1938.  *  name has been specified. if the Property is not a COMPOSITE then
  1939.  *  ZERO is returned.
  1940.  */
  1941. INT32
  1942. CommonRegistry::Count(const char* prop_name) const
  1943. {
  1944.     DB_node* d = 0;
  1945.     Property* p = 0;
  1946.     DB_implem* ldb = 0;
  1947.     UINT32 h = 0;
  1948.     if (_find(&d, &p, prop_name) != HXR_OK)
  1949. return 0;
  1950.     if (p)
  1951.     {
  1952. if (p->get_type() == PT_COMPOSITE)
  1953. {
  1954.     p->get_db_val(&ldb);
  1955.     if (ldb)
  1956. return ldb->count();
  1957. }
  1958.     }
  1959.     return 0;
  1960. }
  1961. /*
  1962.  *  Function Name:   CommonRegistry::Count
  1963.  *  Input Params:    const UINT32 hash_key
  1964.  *  Return Value:    UINT32
  1965.  *  Description:
  1966.  *   returns the number of Properties below the COMPOSITE whose
  1967.  *  hash key has been specified. if the Property is not a COMPOSITE
  1968.  *  then ZERO is returned.
  1969.  */
  1970. INT32
  1971. CommonRegistry::Count(const UINT32 hash_key) const
  1972. {
  1973.     DB_node* d = 0;
  1974.     Property* p = 0;
  1975.     DB_implem* ldb = 0;
  1976.     d = (DB_node *)_ids->get(hash_key);
  1977.     if (!d)
  1978.     {
  1979. DPRINTF(D_REGISTRY, ("%lu -- does not existn", hash_key));
  1980. return HXR_FAIL;
  1981.     }
  1982.     p = d->get_data();
  1983.     if (p)
  1984.     {
  1985. if (p->get_type() == PT_COMPOSITE)
  1986. {
  1987.     p->get_db_val(&ldb);
  1988.     if (ldb)
  1989. return ldb->count();
  1990. }
  1991.     }
  1992.     return 0;
  1993. }
  1994. /*
  1995.  *  Function Name:   CommonRegistry::_del
  1996.  *  Input Params:    DB_implem* db
  1997.  *  Return Value:    HX_RESULT
  1998.  *  Description:
  1999.  *   recursive delete down the database, which simultaneously
  2000.  *  deletes nodes from the hash tree. this method gets called from
  2001.  *  Del() when the user wants to delete a COMPOSITE Property. the
  2002.  *  default action is to delete all Properties under that COMPOSITE.
  2003.  */
  2004. HX_RESULT
  2005. CommonRegistry::_del(DB_implem* db)
  2006. {
  2007.     DPRINTF(D_REGISTRY, ("_del(db(%p)n", db));
  2008.     DB_node* d = db->first();
  2009.     while (d)
  2010.     {
  2011. Property* pnode = d->get_data();
  2012. DPRINTF(D_REGISTRY, ("_del(db(%p)) -- %s(%lu)n", db, 
  2013. pnode->get_key_str(), d->get_id()));
  2014. if (pnode)
  2015. {
  2016.     if (pnode->get_type() == PT_COMPOSITE)
  2017.     {
  2018. DB_implem* ldb;
  2019. pnode->get_db_val(&ldb);
  2020. if (!ldb)
  2021. {
  2022.     DPRINTF(D_REGISTRY, ("invalid Property(%lu) not deletedn",
  2023.                          d->get_id()));
  2024.     return HXR_FAIL;
  2025. }
  2026. _del(ldb);
  2027.     }
  2028.     // fire off the callbacks if someone is watching this prop
  2029.     DeleteDone(db, d, pnode);
  2030.     _ids->destroy(d->get_id());
  2031.     db->del(d);
  2032.     _count--;
  2033. }
  2034. else
  2035. {
  2036.     DPRINTF(D_REGISTRY, ("data corrputed for Property(%lu)n",
  2037.                          d->get_id()));
  2038.     return HXR_FAIL;
  2039. }
  2040. d = db->first();
  2041.     }
  2042.     return HXR_OK;
  2043. }
  2044. /*
  2045.  *  Function Name:   CommonRegistry::_getPropList const
  2046.  *  Input Params:    DB_implem* ldb, IHXValues*& pValues
  2047.  *  Return Value:    HX_RESULT
  2048.  *  Description:
  2049.  *   return back a list of triples (name, type, hash) consisting of
  2050.  *  all the properties in the database level specified by "ldb". this
  2051.  *  method is generally called from GetPropList() when a user requests 
  2052.  *  for a list of Properties under some COMPOSITE Property.
  2053.  */
  2054. HX_RESULT
  2055. CommonRegistry::_getPropList(DB_implem* ldb, IHXValues*& pValues) const
  2056. {
  2057.     DPRINTF(D_REGISTRY, ("_getPropList(ldb(%p))n", ldb));
  2058.     DB_node*  node = 0;
  2059.     pValues = new CHXHeader;
  2060.     pValues->AddRef();
  2061.     node = ldb->first();
  2062.     while (node)
  2063.     {
  2064. Property* p = node->get_data();
  2065. if (!p)
  2066. {
  2067.     DPRINTF(D_REGISTRY, ("%ld is an empty Registry node, skipping itn",
  2068.                          node->get_id()));
  2069. }
  2070. pValues->SetPropertyULONG32(p->get_key_str(), node->get_id());
  2071. DB_node* n = ldb->next(node);
  2072. node = n;
  2073.     }
  2074.     return HXR_OK;
  2075. }
  2076. /*
  2077.  *  Copyright (c) 1996, 1997, 1998 RealNetworks
  2078.  *
  2079.  *  Function Name:   CommonRegistry::_setReadOnly
  2080.  *  Input Params:    Property* pProp, BOOL bValue
  2081.  *  Return Value:    HX_RESULT
  2082.  *  Description:
  2083.  *   set the read_only flag of this node, and all nodes beneath
  2084.  * this node (if this node is a composite) to bValue.
  2085.  */
  2086. HX_RESULT
  2087. CommonRegistry::_setReadOnly(Property* pProp, BOOL bValue)
  2088. {
  2089.     DB_implem* ldb  = 0;
  2090.     DB_node*   node = 0;
  2091.     // Set read_only flag on pProp
  2092.     pProp->set_read_only(bValue);
  2093.     if (pProp->get_type() == PT_COMPOSITE)
  2094.     {
  2095. // Get ldb of pProp
  2096. pProp->get_db_val(&ldb);
  2097. if (ldb)
  2098. {
  2099.     // Set read_only flag on each child
  2100.     node = ldb->first();
  2101.     while (node)
  2102.     {
  2103. Property* p = node->get_data();
  2104. if (!p)
  2105. {
  2106.     DPRINTF(D_REGISTRY, ("%ld is an empty Registry node, "
  2107. "skipping itn", node->get_id()));
  2108. }
  2109. // Recurse...
  2110. _setReadOnly(p, bValue);
  2111. DB_node* n = ldb->next(node);
  2112. node = n;
  2113.     }
  2114. }
  2115.     }
  2116.     return HXR_OK;
  2117. }
  2118. /*
  2119.  *  Function Name:   _find
  2120.  *  Input Params:    DB_node** d, Property** p, 
  2121.  *                      UINT32& hash_key, const char* prop_name
  2122.  *  Return Value:    HX_RESULT
  2123.  *  Description:
  2124.  *   find a DB_node and its corresponding Property based on the name
  2125.  *  or the hash key, whichever is given.
  2126.  */
  2127. HX_RESULT
  2128. CommonRegistry::_find(DB_node** d, Property** p, const char* prop_name) const
  2129. {
  2130.     DPRINTF(D_REGISTRY, ("CommonRegistry::_find(prop_name(%s))n", prop_name));
  2131.     Key* k = new Key(prop_name);
  2132.     if(!k)
  2133.     {
  2134.         return 0;
  2135.     }
  2136.     int len = k->size();
  2137.     char* curr_key_str = new char[len];
  2138.     if(NULL==curr_key_str)
  2139.     {
  2140.         HX_DELETE(k);
  2141.         return 0;
  2142.     }
  2143.     DB_implem* ldb = _logdb_imp;
  2144.     HX_RESULT ret = HXR_OK;
  2145.     // find the node that contains the "prop_name"
  2146.     *curr_key_str = '';
  2147.     while(k->append_sub_str(curr_key_str, len))
  2148.     {
  2149. if (!ldb)
  2150. {
  2151.     DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!n",
  2152.                          prop_name, curr_key_str));
  2153.     ret = HXR_FAIL;
  2154.     goto cleanup;
  2155. }
  2156. *d = ldb->find(curr_key_str);
  2157. if (!(*d))
  2158. {
  2159.     DPRINTF(D_REGISTRY, ("%s -- %s was NOT FOUNDn",
  2160.                          prop_name, curr_key_str));
  2161.     ret = HXR_PROP_NOT_FOUND;
  2162.     goto cleanup;
  2163. }
  2164. *p = (*d)->get_data();
  2165.         if (!(*p))
  2166. {
  2167.     DPRINTF(D_REGISTRY, ("%s -- %s has NO DATAn",
  2168.                          prop_name, curr_key_str));
  2169.             ret = HXR_FAIL;
  2170.     goto cleanup;
  2171. }
  2172. if ((*p)->get_type() == PT_COMPOSITE)
  2173.     (*p)->get_db_val(&ldb);
  2174.     }
  2175.     if (*d && *p)
  2176. ret = HXR_OK;
  2177.     else
  2178. ret = HXR_FAIL;
  2179. cleanup:
  2180.     HX_VECTOR_DELETE(curr_key_str);
  2181.     delete k;
  2182.     return ret;
  2183. }