📄 commreg.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
// #include <stdio.h>
#include "hlxclib/stdlib.h"
#include "hlxclib/string.h"
#include "hxtypes.h"
#include "debug.h"
#include "ihxpckts.h"
#include "hxmon.h"
#include "hxstrutl.h"
#include "chxpckts.h"
#include "db_misc.h"
#include "key.h"
#include "watchlst.h"
#include "property.h"
#include "db_dict_abs.h"
#include "db_dict.h"
#include "id.h"
#include "commreg.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
CommonRegistry::CommonRegistry()
: _count(0)
, m_pWatchList(NULL)
, m_lWatchCount(0)
, m_LastError(HXR_OK)
{
_logdb_imp = new DB_dict;
if(!_logdb_imp)
{
m_LastError = HXR_OUTOFMEMORY;
}
_ids = new CHXID(1000);
if(!_ids)
{
m_LastError = HXR_OUTOFMEMORY;
}
DPRINTF(D_REGISTRY, ("CommonRegistry::CommonRegistry -- _logdb_imp(%p), "
"_ids(%p)\n", _logdb_imp, _ids));
}
CommonRegistry::~CommonRegistry()
{
if (_logdb_imp)
delete _logdb_imp;
if (_ids)
delete _ids;
}
/*
* Function Name: AddComp
* Input Params: char * prop_name
* Return Value: UINT32
* Description:
* function for adding PT_COMPOSITE nodes in the log database.
* PT_COMPOSITE nodes can contain other nodes, this is the structure
* demanded by the hierarchical storage.
*/
UINT32
CommonRegistry::AddComp(const char* prop_name)
{
DPRINTF(D_REGISTRY, ("CommonRegistry::AddComp(%s)\n", prop_name));
HX_RESULT theErr = HXR_OK;
DB_node* d = 0;
Property* p = 0;
Key* k = new Key(prop_name);
if(!k)
{
return 0;
}
int len = k->size();
char* curr_key_str = new char[len];
if(!curr_key_str)
{
HX_DELETE(k);
return 0;
}
DB_implem* ldb = _logdb_imp;
DB_node* new_d = NULL;
BOOL read_only = FALSE;
/*
* check if all but the last sub-strings are already present
* eg.
* if foo.bar.moo is to be added then
* the following loop checks is "foo" and "bar"
* have already been created
* after the while loop one final check is made to check
* if "moo" NOT already present to avoid adding a DUPLICATE
*/
*curr_key_str = '\0';
while(!k->last_sub_str())
{
k->append_sub_str(curr_key_str, len);
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
if (!ldb)
{
DPRINTF(D_INFO, ("%s -- %s has NO Properties under it!\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
d = ldb->find(curr_key_str);
if (!d)
{
DPRINTF(D_REGISTRY, ("%s -- %s was NOT FOUND\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
p = d->get_data();
if (!p)
{
DPRINTF(D_REGISTRY, ("%s -- %s has NO DATA\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
read_only = p->is_read_only();
if (read_only)
{
DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLY\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
}
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
k->append_sub_str(curr_key_str, len);
if (ldb->find(curr_key_str))
{
DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!\n", k->get_key_str()));
theErr = HXR_FAILED;
goto cleanup;
}
// everything is alright add the new property
new_d = _addComp(k, curr_key_str, ldb);
AddDone(ldb, new_d, d, p);
cleanup:
HX_VECTOR_DELETE(curr_key_str);
if (HXR_OK != theErr)
{
if (k)
{
delete k;
k = NULL;
}
return 0;
}
else
{
return new_d->get_id();
}
}
UINT32
CommonRegistry::_buildSubstructure4Prop(const char* pFailurePoint,
const char* pProp)
{
/*
* A lower composite was not there.
* Add all of the composites up the to prop.
*/
UINT32 len = strlen(pProp) + 1;
Key* lame = new Key(pProp);
char* temp_key_str = new char[len];
*temp_key_str = 0;
while (strlen(temp_key_str) < strlen(pFailurePoint))
{
lame->append_sub_str(temp_key_str, len);
}
int ret;
while ((ret = AddComp(temp_key_str)) != 0)
{
if (lame->last_sub_str())
{
break;
}
lame->append_sub_str(temp_key_str, len);
}
delete[] temp_key_str;
delete lame;
lame = 0;
return ret;
}
/*
* Function Name: AddInt
* Input Params: const char* prop_name, const INT32 val
* Return Value: UINT32
* Description:
* function to add a property which has an integer value, to
* the log database. this will add all the USER DEFINED properties.
*/
UINT32
CommonRegistry::AddInt(const char* prop_name, const INT32 val)
{
DPRINTF(D_REGISTRY, ("CommonRegistry::AddInt(%s, %ld)\n", prop_name, val));
HX_RESULT theErr = HXR_OK;
DB_node* d = 0;
Property* p = 0;
Key* k = new Key(prop_name);
if(!k)
{
return 0;
}
int len = k->size();
char* curr_key_str = new char[len];
if(!curr_key_str)
{
HX_DELETE(k);
return 0;
}
DB_implem* ldb = _logdb_imp;
DB_node* new_d = NULL;
BOOL read_only = FALSE;
*curr_key_str = '\0';
while(!k->last_sub_str())
{
k->append_sub_str(curr_key_str, len);
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
if (!ldb)
{
DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
d = ldb->find(curr_key_str);
if (!d)
{
int ret = _buildSubstructure4Prop(curr_key_str,
prop_name);
if (ret)
{
d = ldb->find(curr_key_str);
}
if (!ret || !d)
{
theErr = HXR_FAILED;
goto cleanup;
}
}
p = d->get_data();
if (!p)
{
DPRINTF(D_REGISTRY, ("%s -- %s has NO DATA\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
read_only = p->is_read_only();
if (read_only)
{
DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLY\n",
prop_name, curr_key_str));
theErr = HXR_FAILED;
goto cleanup;
}
}
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
k->append_sub_str(curr_key_str, len);
if (ldb->find(curr_key_str))
{
DPRINTF(D_REGISTRY, ("%s -- is ALREADY PRESENT!\n", k->get_key_str()));
theErr = HXR_FAILED;
goto cleanup;
}
// everything is alright add the new property
new_d = _addInt(k, curr_key_str, val, ldb);
AddDone(ldb, new_d, d, p);
cleanup:
HX_VECTOR_DELETE(curr_key_str);
if (HXR_OK != theErr)
{
if (k)
{
delete k;
k = NULL;
}
return 0;
}
else
{
return new_d->get_id();
}
}
/*
* Function Name: GetInt
* Input Params: const char* prop_name, INT32* value
* Return Value: HX_RESULT
* Description:
* retrieve the INTEGER property if it exists.
*/
HX_RESULT
CommonRegistry::GetInt(const char* prop_name, INT32* value) const
{
DB_node* d = 0;
Property* p = 0;
if (_find(&d, &p, prop_name) != HXR_OK)
return HXR_FAIL;
if (p)
{
switch(p->get_type())
{
case PT_INTEGER:
return p->get_int_val(value);
break;
case PT_INTREF:
return p->get_int_ref_val(value);
break;
default:
DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCH\n",
prop_name));
return HXR_PROP_TYPE_MISMATCH;
}
}
return HXR_FAIL;
}
/*
* Function Name: GetInt
* Input Params: const UINT32 hash_key, INT32* value
* Return Value: HX_RESULT
* Description:
* retrieve the INTEGER property using the HashTree.
*/
HX_RESULT
CommonRegistry::GetInt(const UINT32 hash_key, INT32* value) const
{
DB_node* d = 0;
Property* p = 0;
d = (DB_node *)_ids->get(hash_key);
if (!d)
{
DPRINTF(D_REGISTRY, ("GetInt(%lu) failed\n", hash_key));
return HXR_FAIL;
}
p = d->get_data();
if (p)
{
switch(p->get_type())
{
case PT_INTEGER:
return p->get_int_val(value);
break;
case PT_INTREF:
return p->get_int_ref_val(value);
break;
default:
DPRINTF(D_REGISTRY, ("%lu -- Property<-->Type MISMATCH\n",
hash_key));
return HXR_PROP_TYPE_MISMATCH;
}
}
return HXR_FAIL;
}
/*
* Function Name: SetInt
* Input Params: const char* prop_name, const INT32 value
* Return Value: HX_RESULT
* Description:
* sets the value of an integer property.
*/
HX_RESULT
CommonRegistry::SetInt(const char* prop_name, const INT32 value)
{
DB_node* d = 0;
Property* p = 0;
if (_find(&d, &p, prop_name) != HXR_OK)
return HXR_FAIL;
if (!p)
return HXR_FAIL;
if (p->is_read_only())
{
DPRINTF(D_REGISTRY, ("%s -- Property is READ ONLY\n",
prop_name));
return HXR_FAIL;
}
switch(p->get_type())
{
case PT_INTEGER:
p->int_val(value);
break;
case PT_INTREF:
DPRINTF(D_REGISTRY, ("cannot set INTREF value using SetInt\n"));
return HXR_FAIL;
default:
DPRINTF(D_REGISTRY, ("%s -- Property<-->Type MISMATCH\n",
prop_name));
return HXR_PROP_TYPE_MISMATCH;
}
// dispatch the callbacks and then return HXR_OK
return SetDone(d, p);
}
/*
* Function Name: SetInt
* Input Params: const UINT32 hash_key, const INT32 value
* Return Value: HX_RESULT
* Description:
* set a new value of the INTEGER property using the HashTree.
*/
HX_RESULT
CommonRegistry::SetInt(const UINT32 hash_key, const INT32 value)
{
DPRINTF(D_REGISTRY, ("CommonRegistry::SetInt(%lu, %ld)\n", hash_key,
value));
DB_node* d = 0;
Property* p = 0;
d = (DB_node *)_ids->get(hash_key);
if (!d)
{
DPRINTF(D_REGISTRY, ("SetInt(%lu) failed\n", hash_key));
return HXR_FAIL;
}
p = d->get_data();
if (!p)
return HXR_FAIL;
if (p->is_read_only())
{
DPRINTF(D_REGISTRY, ("%s(%lu) -- Property is READ ONLY\n",
p->get_key_str(), hash_key));
return HXR_FAIL;
}
switch(p->get_type())
{
case PT_INTEGER:
p->int_val(value);
break;
case PT_INTREF:
DPRINTF(D_REGISTRY, ("cannot set INTREF value using SetInt\n"));
return HXR_FAIL;
default:
DPRINTF(D_REGISTRY, ("%s(%lu) -- Property<-->Type MISMATCH\n",
p->get_key_str(), hash_key));
return HXR_PROP_TYPE_MISMATCH;
}
// dispatch the callbacks and then return HXR_OK
return SetDone(d, p);
}
/*
* Function Name: CommonRegistry::AddStr
* Input Params: const char* prop_name, const char* const value,
* Return Value: UINT32
* Description:
* adds a STRING Property ot the registry.
*/
UINT32
CommonRegistry::AddStr(const char* prop_name, IHXBuffer* buf)
{
DPRINTF(D_REGISTRY, ("CommonRegistry::AddStr(%s, buf(%p)\n",
prop_name, buf));
DB_node* d = 0;
Property* p = 0;
Key* k = new Key(prop_name);
if(!k)
{
return 0;
}
int len = k->size();
char* curr_key_str = new char[len];
if(!curr_key_str)
{
HX_DELETE(k);
return 0;
}
DB_implem* ldb = _logdb_imp;
BOOL read_only = FALSE;
*curr_key_str = '\0';
while(!k->last_sub_str())
{
k->append_sub_str(curr_key_str, len);
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
if (!ldb)
{
DPRINTF(D_REGISTRY, ("%s -- %s has NO Properties under it!\n",
prop_name, curr_key_str));
delete k;
HX_VECTOR_DELETE(curr_key_str);
return 0;
}
d = ldb->find(curr_key_str);
if (!d)
{
int ret = _buildSubstructure4Prop(curr_key_str,
prop_name);
if (!ret)
{
delete k;
delete[] curr_key_str;
return 0;
}
d = ldb->find(curr_key_str);
if (!d)
{
delete k;
delete[] curr_key_str;
return 0;
}
}
p = d->get_data();
if (!p)
{
DPRINTF(D_REGISTRY, ("%s -- %s has NO DATA\n",
prop_name, curr_key_str));
delete k;
HX_VECTOR_DELETE(curr_key_str);
return 0;
}
read_only = p->is_read_only();
if (read_only)
{
DPRINTF(D_REGISTRY, ("%s -- %s is READ ONLY\n",
prop_name, curr_key_str));
delete k;
HX_VECTOR_DELETE(curr_key_str);
return 0;
}
}
if (p && p->get_type() == PT_COMPOSITE)
p->get_db_val(&ldb);
k->append_sub_str(curr_key_str, len);
if (ldb->find(curr_key_str))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -