commreg.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:56k
源码类别:

Symbian

开发平台:

Visual C++

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