reman3/Rayman_X/cpa/tempgrp/SCR/SCR_Link.c

878 lines
29 KiB
C

/*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* SCR_Link.c
* To manage Link table.
*
* Scripts, Beaudet Christophe
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*
*=================================================================================================
* Includes.
*=================================================================================================
*/
#include "SCR.h"
/*
*=================================================================================================
* Global variables.
*=================================================================================================
*/
/* Array of link tables */
SCR_tdst_DyAr_Description SCR_g_st_Link_Array;
#if defined SCR_DM_ProtectedVersion
void fn_v_Link_AssertValidP(SCR_tdst_Link_Table *_p_stLink, SCR_tdst_Link_Value *_p_stEntry)
{
SCR_M_Dbg_Assert_P
(
_p_stEntry->stHeader.ucMemLevel
== ((SCR_tdst_Hash_Value *) (_p_stLink->a_stHashTableForKeys[_p_stEntry->xHashKeyForKey]
.d_stDynArray[_p_stEntry->uiIndexHashKeyKey].d_vElement))
->stHeader.ucMemLevel
);
SCR_M_Dbg_Assert_P
(
_p_stEntry->stHeader.ucMemLevel
== ((SCR_tdst_Hash_Value *) (_p_stLink->a_stHashTableForValues[_p_stEntry->xHashKeyForValue]
.d_stDynArray[_p_stEntry->uiIndexHashKeyValue].d_vElement))
->stHeader.ucMemLevel
);
}
#else
#define fn_v_Link_AssertValidP(a, b)
#endif /* SCR_DM_ProtectedVersion */
/*
*=================================================================================================
* Functions.
*=================================================================================================
*/
/*
*-------------------------------------------------------------------------------------------------
* Init.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Link_InitModule(void)
{
fn_v_DyAr_InitArray(&SCR_g_st_Link_Array);
}
/*
*-------------------------------------------------------------------------------------------------
* Close.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Link_CloseModule(void)
{
unsigned int uiIndex;
/*
* Delete all elements.
*/
for(uiIndex = 0; uiIndex < SCR_g_st_Link_Array.uiNumValues; uiIndex++)
if(SCR_g_st_Link_Array.d_stDynArray[uiIndex].d_vElement != NULL)
{
SCR_M_DyAr_DeleteElementNoAlloc
(
uiIndex,
&SCR_g_st_Link_Array,
SCR_fn_v_Link_CloseTable((SCR_tdst_Link_Table *) _p_stElement_->d_vElement);
);
}
/*
* Free array.
*/
if(SCR_g_st_Link_Array.d_stDynArray)
{
fn_v_Mem_SetMode(0);
SCR_M_Mem_Free(SCR_g_st_Link_Array.d_stDynArray);
}
SCR_g_st_Link_Array.uiNumValues = SCR_g_st_Link_Array.uiMaxValues = 0;
}
/*
*-------------------------------------------------------------------------------------------------
* Function that checked if a link table has been register.
* _p_stLink : Link table to search.
* _p_uiIndex : To return (can be NULL) the index of the table in global array.
*-------------------------------------------------------------------------------------------------
*/
char fn_c_Link_CheckForInit(SCR_tdst_Link_Table *_p_stLink, unsigned int *_p_uiIndex)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiIndex;
SCR_tdst_Link_Table *p_stTemp;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
uiIndex = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiIndex, p_stTemp, SCR_g_st_Link_Array);
while(p_stTemp)
{
if(p_stTemp == _p_stLink)
{
if(_p_uiIndex)
*_p_uiIndex = uiIndex;
return 1;
}
uiIndex++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiIndex, p_stTemp, SCR_g_st_Link_Array);
}
return 0;
}
/*
*-------------------------------------------------------------------------------------------------
* Init a link table.
* _p_stLink : Link table to init.
*-------------------------------------------------------------------------------------------------
*/
void SCR_fn_v_Link_InitTable(SCR_tdst_Link_Table *_p_stLink)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiIndex;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if(!fn_c_Link_CheckForInit(_p_stLink, NULL))
{
/* Add table in array */
SCR_M_DyAr_AddElementNoAlloc(uiIndex, _p_stLink, SCR_g_st_Link_Array);
/* Init table */
SCR_M_Dbg_UpdateSizeOf_P(SCR_tdst_Link_Table, _p_stLink);\
fn_v_DyAr_InitArray(&_p_stLink->stLinkArray);
fn_v_Hash_InitTable(_p_stLink->a_stHashTableForValues);
fn_v_Hash_InitTable(_p_stLink->a_stHashTableForKeys);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(;)
/*
*-------------------------------------------------------------------------------------------------
* Really delete a link table.
* _p_stLink : Link table to delete.
*-------------------------------------------------------------------------------------------------
*/
void SCR_fn_v_Link_CloseTable(SCR_tdst_Link_Table *_p_stLink)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiIndex;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Delete element from table */
if(fn_c_Link_CheckForInit(_p_stLink, &uiIndex))
SCR_M_DyAr_DeleteElementNoAlloc(uiIndex, &SCR_g_st_Link_Array, ;);
/* Delete content */
SCR_M_DyAr_DeleteAllElements
(
SCR_tdst_Link_Value,
&_p_stLink->stLinkArray,
{
fn_v_Link_AssertValidP(_p_stLink, _p_stPointer_);
fn_v_Mem_SetMode(_p_stPointer_->stHeader.ucMemLevel);
SCR_M_Mem_Free(_p_stPointer_->p_szKey);
}
);
fn_v_Hash_CloseTable(_p_stLink->a_stHashTableForValues);
fn_v_Hash_CloseTable(_p_stLink->a_stHashTableForKeys);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(;)
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* Add an entry to a link table
* _p_stLink : Link table
* _p_szKey : String key of value
* _ulValue : Value to set in structure
* _eState : State of that value
* Returns pointer on added link.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Link_Value *SCR_fnp_st_Link_AddEntry
(
SCR_tdst_Link_Table *_p_stLink,
char *_p_szKey,
unsigned long _ulValue,
SCR_tde_Link_State _eState
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiIndex;
SCR_tdst_Link_Value *p_stLinkValue;
unsigned char ucMemoLevel;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
SCR_M_Dbg_Assert_D(_p_szKey != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/***************************************************/
ucMemoLevel = g_uc_Mem_CurrentMemLevel;
g_uc_Mem_CurrentMemLevel = g_uc_Mem_CurrentLinkLevel;
/***************************************************/
/* If assertion failed, link table has not been properly init with script function */
SCR_M_Dbg_Assert_D(fn_c_Link_CheckForInit(_p_stLink, NULL));
/*
* Add a new link value in link value array.
*/
SCR_M_DyAr_AddElement(SCR_tdst_Link_Value, uiIndex, p_stLinkValue, _p_stLink->stLinkArray);
/*
* Initialize structure.
*/
p_stLinkValue->eState = _eState;
p_stLinkValue->ulValue = _ulValue;
if(_eState == SCR_ELS_Link_Initialized)
{
p_stLinkValue->xHashKeyForValue = SCR_fn_x_Hash_ComputeHashKeyForLong(_ulValue);
fnp_st_Hash_AddValue
(
p_stLinkValue->xHashKeyForValue,
_p_stLink->a_stHashTableForValues,
(unsigned long) p_stLinkValue,
&p_stLinkValue->uiIndexHashKeyValue
);
}
else
{
/* Not initialized */
p_stLinkValue->xHashKeyForValue = SCR_C_ui_Hash_Modulo;
}
fn_v_Mem_SetMode(p_stLinkValue->stHeader.ucMemLevel);
SCR_M_Mem_Alloc(char, p_stLinkValue->p_szKey, strlen(_p_szKey) + 1);
strcpy(p_stLinkValue->p_szKey, _p_szKey);
p_stLinkValue->xHashKeyForKey = SCR_fn_x_Hash_ComputeHashKeyForString(_p_szKey);
fnp_st_Hash_AddValue
(
p_stLinkValue->xHashKeyForKey,
_p_stLink->a_stHashTableForKeys,
(unsigned long) p_stLinkValue,
&p_stLinkValue->uiIndexHashKeyKey
);
/*
* Initialize additional informations.
*/
memset(&p_stLinkValue->stInfos, 0, sizeof(SCR_tdst_Link_AdditionalInfos));
/***************************************************/
fn_v_Link_AssertValidP(_p_stLink, p_stLinkValue);
g_uc_Mem_CurrentMemLevel = ucMemoLevel;
/***************************************************/
SCR_RETURN(p_stLinkValue);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(NULL)
/*
*-------------------------------------------------------------------------------------------------
* Get Link for a specific key. Create it if it does not exist yet.
* _p_stLink : Link table to search
* _p_szKey : String key of value
* Returns founded or created link.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Link_Value *SCR_fnp_st_Link_CreateOrGetLinkFromKey
(
SCR_tdst_Link_Table *_p_stLink,
char *_p_szKey
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Link_Value *p_stLinkValue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
SCR_M_Dbg_Assert_D(_p_szKey != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* We first search if there's already a key in link table.
*/
p_stLinkValue = SCR_fnp_st_Link_SearchKey(_p_stLink, _p_szKey);
/*
* Key is not here, add it.
*/
if(p_stLinkValue == NULL)
{
p_stLinkValue = SCR_fnp_st_Link_AddEntry
(
_p_stLink,
_p_szKey,
0x12345678,
SCR_ELS_Link_NotInitialized
);
}
SCR_RETURN(p_stLinkValue);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(NULL)
/*
*-------------------------------------------------------------------------------------------------
* Set the ulValue of a specific key.
* _p_stLink : Link table to search
* _p_szKey : String key of value
* _ulValue : Value to set
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Link_Value *SCR_fnp_st_Link_SetValue
(
SCR_tdst_Link_Table *_p_stLink,
char *_p_szKey,
unsigned long _ulValue
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_tdst_Link_Value *p_stLinkValue;
unsigned char ucMemoLevel;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
SCR_M_Dbg_Assert_D(_p_szKey != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* We first search the key in the link table.
*/
p_stLinkValue = SCR_fnp_st_Link_SearchKey(_p_stLink, _p_szKey);
/*
* No key found, add one.
*/
if(p_stLinkValue == NULL)
{
SCR_RETURN(SCR_fnp_st_Link_AddEntry
(
_p_stLink,
_p_szKey,
_ulValue,
SCR_ELS_Link_Initialized
));
}
/*
* We have found an already registered link.
* Initialized the found structure.
*/
else
{
/*
* If value replaced another one, we must delete actual hash.
*/
if(p_stLinkValue->xHashKeyForValue != SCR_C_ui_Hash_Modulo)
{
SCR_M_DyAr_DeleteElement
(
SCR_tdst_Hash_Value,
p_stLinkValue->uiIndexHashKeyValue,
&_p_stLink->a_stHashTableForValues[p_stLinkValue->xHashKeyForValue],
;
);
}
/*
* Initialize new value.
*/
/***************************************************/
ucMemoLevel = g_uc_Mem_CurrentMemLevel;
g_uc_Mem_CurrentMemLevel = p_stLinkValue->stHeader.ucMemLevel;
/***************************************************/
p_stLinkValue->ulValue = _ulValue;
p_stLinkValue->xHashKeyForValue = SCR_fn_x_Hash_ComputeHashKeyForLong(_ulValue);
p_stLinkValue->eState = SCR_ELS_Link_Initialized;
fnp_st_Hash_AddValue
(
p_stLinkValue->xHashKeyForValue,
_p_stLink->a_stHashTableForValues,
(unsigned long) p_stLinkValue,
&p_stLinkValue->uiIndexHashKeyValue
);
/***************************************************/
g_uc_Mem_CurrentMemLevel = ucMemoLevel;
/***************************************************/
SCR_RETURN(p_stLinkValue);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(NULL)
/*===============================================================================================*/
/*
*-------------------------------------------------------------------------------------------------
* Search a key in a link table.
* _p_stLink : Link table to search
* _p_szKey : String key of value
* Returns pointer on found link or NULL.
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Link_Value *SCR_fnp_st_Link_SearchKey
(
SCR_tdst_Link_Table *_p_stLink,
char *_p_szKey
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_DyAr_Description *p_stHashEntry;
SCR_tdst_Hash_Value *p_stHashValue;
SCR_tdst_Link_Value *p_stLinkValue;
SCR_tdx_Hash_Key xHashKey;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
SCR_M_Dbg_Assert_D(_p_szKey != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Compute hash key for given string
*/
xHashKey = SCR_fn_x_Hash_ComputeHashKeyForString(_p_szKey);
/*
* If there's no dynamic array associated to this hash key code,
* we are sure that data was not stored in the array.
*/
p_stHashEntry = &_p_stLink->a_stHashTableForKeys[xHashKey];
/*
* Else we search in the array (that contains all the datas with the
* same hash key code) if our data is present.
*/
uiPos = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Hash_Value, uiPos, p_stHashValue, (*p_stHashEntry));
while(p_stHashValue)
{
p_stLinkValue = (SCR_tdst_Link_Value *) p_stHashValue->ulValue;
if(!strcmpi(p_stLinkValue->p_szKey, _p_szKey))
SCR_RETURN(p_stLinkValue);
uiPos++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Hash_Value, uiPos, p_stHashValue, (*p_stHashEntry));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(NULL)
/*
*-------------------------------------------------------------------------------------------------
* Search a value in a link table
* _p_stLink Link table to search
* _ulValue value to search for
* Returns pointer on found link or NULL
*-------------------------------------------------------------------------------------------------
*/
SCR_tdst_Link_Value *SCR_fnp_st_Link_SearchValue
(
SCR_tdst_Link_Table *_p_stLink,
unsigned long _ulValue
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPos;
SCR_tdst_DyAr_Description *p_stHashEntry;
SCR_tdst_Hash_Value *p_stHashValue;
SCR_tdst_Link_Value *p_stLinkValue;
SCR_tdx_Hash_Key xHashKey;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_M_Dbg_Assert_D(_p_stLink != NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Compute hash key for given string.
*/
xHashKey = SCR_fn_x_Hash_ComputeHashKeyForLong(_ulValue);
/*
* Get hash entry for computed Hash key code.
*/
p_stHashEntry = &_p_stLink->a_stHashTableForValues[xHashKey];
/*
* Else we search in the array (that contains all the datas with the
* same hash key code) if our data is present.
*/
uiPos = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Hash_Value, uiPos, p_stHashValue, (*p_stHashEntry));
while(p_stHashValue)
{
p_stLinkValue = (SCR_tdst_Link_Value *) p_stHashValue->ulValue;
if(p_stLinkValue->ulValue == _ulValue)
SCR_RETURN(p_stLinkValue);
uiPos++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Hash_Value, uiPos, p_stHashValue, (*p_stHashEntry));
}
SCR_RETURN(NULL);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(NULL)
/*
*-------------------------------------------------------------------------------------------------
* Delete an entry in a link table.
* _p_stLink Link table to search
* _p_stEntry Entry to delete.
*-------------------------------------------------------------------------------------------------
*/
void SCR_fn_v_Link_DeleteEntry
(
SCR_tdst_Link_Table *_p_stLink,
SCR_tdst_Link_Value *_p_stEntry
)
SCR_BEGIN
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
fn_v_Link_AssertValidP(_p_stLink, _p_stEntry);
/*
* Delete in the two hash tables.
*/
SCR_M_DyAr_DeleteElement
(
SCR_tdst_Hash_Value,
_p_stEntry->uiIndexHashKeyKey,
&_p_stLink->a_stHashTableForKeys[_p_stEntry->xHashKeyForKey],
;
);
SCR_M_DyAr_DeleteElement
(
SCR_tdst_Hash_Value,
_p_stEntry->uiIndexHashKeyValue,
&_p_stLink->a_stHashTableForValues[_p_stEntry->xHashKeyForValue],
;
);
/*
* Delete link value in array.
*/
SCR_M_DyAr_DeleteElement
(
SCR_tdst_Link_Value,
_p_stEntry->stHeader.uiIndexInArray,
&_p_stLink->stLinkArray,
{
fn_v_Mem_SetMode(_p_stPointer_->stHeader.ucMemLevel);
SCR_M_Mem_Free(_p_stPointer_->p_szKey);
}
);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SCR_CEND(;)
/*
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
*/
/*
*-------------------------------------------------------------------------------------------------
* To save a link table on disk.
* _p_szName : Name of link table to save.
* _p_stLink : Link table to save.
* _p_CallBack : Call back that will be called for every entries saved.
*-------------------------------------------------------------------------------------------------
*/
void _SCR_fn_v_Link_SaveOnDisk_
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink,
SCR_tdpfn_Link_Callback _p_CallBack
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
FILE *p_xHandle;
unsigned int uiPos, uiSizeOfKey;
SCR_tdst_Link_Value *p_stLinkValue;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* If assertion failed, link table has not been properly init with script function */
SCR_M_Dbg_Assert_D(fn_c_Link_CheckForInit(_p_stLink, NULL));
/*
* Pack table before saving.
* No save if table is empty.
*/
SCR_M_DyAr_PackArray(SCR_tdst_Link_Value, _p_stLink->stLinkArray, ;);
SCR_M_Hash_PackArray(_p_stLink->a_stHashTableForValues, SCR_tdst_Link_Value, _p_stLink->stLinkArray, xHashKeyForValue, uiIndexHashKeyValue);
SCR_M_Hash_PackArray(_p_stLink->a_stHashTableForKeys, SCR_tdst_Link_Value, _p_stLink->stLinkArray, xHashKeyForKey, uiIndexHashKeyKey);
if(_p_stLink->stLinkArray.uiNumValues == 0)
return;
/*
* Open the file for writing.
*/
p_xHandle = fopen(_p_szName, "wb");
if(p_xHandle == NULL)
{
sprintf(g_st_Err_GlobalError.a_szBufferTmp1, "File is \"%s\".", _p_szName);
*g_st_Err_GlobalError.a_szBufferTmp2 = '\0';
SCR_M_Err_RaiseError(SCR_EI_Err_OpenFile);
}
/*
* To save all elements...
*/
uiPos = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value, uiPos, p_stLinkValue, _p_stLink->stLinkArray);
while(p_stLinkValue)
{
if(_p_CallBack)
_p_CallBack(p_stLinkValue);
/* Write length of key */
uiSizeOfKey = strlen(p_stLinkValue->p_szKey) + 1;
fwrite(&uiSizeOfKey, sizeof(int), 1, p_xHandle);
/* Write key */
fwrite(p_stLinkValue->p_szKey, uiSizeOfKey, 1, p_xHandle);
/* Write rest of structure */
fwrite(p_stLinkValue, sizeof(SCR_tdst_Link_Value), 1, p_xHandle);
uiPos++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value, uiPos, p_stLinkValue, _p_stLink->stLinkArray);
}
fclose(p_xHandle);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}
void SCR_fn_v_Link_SaveOnDisk
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink
)
SCR_BEGIN
_SCR_fn_v_Link_SaveOnDisk_(_p_szName, _p_stLink, NULL);
SCR_CEND(;)
void SCR_fn_v_Link_SaveOnDiskWithCallBack
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink,
SCR_tdpfn_Link_Callback _p_CallBack
)
SCR_BEGIN
_SCR_fn_v_Link_SaveOnDisk_(_p_szName, _p_stLink, _p_CallBack);
SCR_CEND(;)
/*
*-------------------------------------------------------------------------------------------------
* To load a link table from disk.
* _p_szName : Name of link table to save.
* _p_stLink : Link table to save.
* _p_CallBack : Call back that will be called for every entries added in the array.
*-------------------------------------------------------------------------------------------------
*/
void _SCR_fn_v_Link_LoadFromDisk_
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink,
SCR_tdpfn_Link_Callback _p_CallBack
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
FILE *p_xHandle;
SCR_tdst_Link_Value stLinkValue, *p_stLinkValue;
unsigned int uiIndex, uiSizeOfKey;
unsigned char ucMemoLevel;
char *p_szTempKey;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* If assertion failed, link table has not been properly init with script function */
SCR_M_Dbg_Assert_D(fn_c_Link_CheckForInit(_p_stLink, NULL));
/*
* Open the file for reading.
*/
p_xHandle = fopen(_p_szName, "rb");
if(p_xHandle == NULL)
return;
/*
* Read the file.
*/
while(!feof(p_xHandle))
{
/* Read size of key */
if(fread(&uiSizeOfKey, sizeof(int), 1, p_xHandle))
{
fn_v_Mem_SetMode(g_uc_Mem_CurrentLinkLevel);
SCR_M_Mem_Alloc(char, p_szTempKey, uiSizeOfKey);
/* Read key */
if(fread(p_szTempKey, uiSizeOfKey, 1, p_xHandle))
{
/* Read structure */
if(fread(&stLinkValue, sizeof(SCR_tdst_Link_Value), 1, p_xHandle))
{
if(!SCR_fnp_st_Link_SearchKey(_p_stLink, p_szTempKey))
{
/***************************************************/
ucMemoLevel = g_uc_Mem_CurrentMemLevel;
g_uc_Mem_CurrentMemLevel = g_uc_Mem_CurrentLinkLevel;
/***************************************************/
/* Add a new link value */
SCR_M_DyAr_AddElement(SCR_tdst_Link_Value, uiIndex, p_stLinkValue, _p_stLink->stLinkArray);
/* Copy loaded value to this new one */
memcpy(p_stLinkValue, &stLinkValue, sizeof(SCR_tdst_Link_Value));
/* Init fields that can't be copied */
p_stLinkValue->p_szKey = p_szTempKey;
p_stLinkValue->stHeader.uiIndexInArray = uiIndex;
if(p_stLinkValue->eState == SCR_ELS_Link_Initialized)
{
fnp_st_Hash_AddValue
(
p_stLinkValue->xHashKeyForValue,
_p_stLink->a_stHashTableForValues,
(unsigned long) p_stLinkValue,
&p_stLinkValue->uiIndexHashKeyValue
);
}
fnp_st_Hash_AddValue
(
p_stLinkValue->xHashKeyForKey,
_p_stLink->a_stHashTableForKeys,
(unsigned long) p_stLinkValue,
&p_stLinkValue->uiIndexHashKeyKey
);
/***************************************************/
g_uc_Mem_CurrentMemLevel = ucMemoLevel;
/***************************************************/
/* Call the callback */
if(_p_CallBack)
_p_CallBack(p_stLinkValue);
}
else
{
fn_v_Mem_SetMode(g_uc_Mem_CurrentLinkLevel);
SCR_M_Mem_Free(p_szTempKey);
}
}
}
}
}
fclose(p_xHandle);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}
void SCR_fn_v_Link_LoadFromDisk
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink
)
SCR_BEGIN
_SCR_fn_v_Link_LoadFromDisk_(_p_szName, _p_stLink, NULL);
SCR_CEND(;)
void SCR_fn_v_Link_LoadFromDiskWithCallBack
(
char *_p_szName,
SCR_tdst_Link_Table *_p_stLink,
SCR_tdpfn_Link_Callback _p_CallBack
)
SCR_BEGIN
_SCR_fn_v_Link_LoadFromDisk_(_p_szName, _p_stLink, _p_CallBack);
SCR_CEND(;)
/*
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
**************************************************************************************************
*/
/*
*-------------------------------------------------------------------------------------------------
* To reduce memory size.
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Link_ReduceMemory(void)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPosTables;
SCR_tdst_Link_Table *p_stLinkTable;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Pack array of link tables */
SCR_M_DyAr_PackArray(SCR_tdst_Link_Table, SCR_g_st_Link_Array, ;);
/* Pack all registered link tables */
uiPosTables = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiPosTables, p_stLinkTable, SCR_g_st_Link_Array);
while(p_stLinkTable)
{
SCR_M_DyAr_PackArray(SCR_tdst_Link_Value, p_stLinkTable->stLinkArray, ;);
SCR_M_Hash_PackArray(p_stLinkTable->a_stHashTableForValues, SCR_tdst_Link_Value, p_stLinkTable->stLinkArray, xHashKeyForValue, uiIndexHashKeyValue);
SCR_M_Hash_PackArray(p_stLinkTable->a_stHashTableForKeys, SCR_tdst_Link_Value, p_stLinkTable->stLinkArray, xHashKeyForKey, uiIndexHashKeyKey);
uiPosTables++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiPosTables, p_stLinkTable, SCR_g_st_Link_Array);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}
/*
*-------------------------------------------------------------------------------------------------
*-------------------------------------------------------------------------------------------------
*/
void fn_v_Link_DeleteWithMemLevel
(
unsigned char _ucMin,
unsigned char _ucMax
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned int uiPosTables;
SCR_tdst_Link_Table *p_stLinkTable;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
uiPosTables = 0;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiPosTables, p_stLinkTable, SCR_g_st_Link_Array);
while(p_stLinkTable)
{
SCR_M_DyAr_DeleteElementWithMemLevel
(
SCR_tdst_Link_Value,
p_stLinkTable->stLinkArray,
{
if(_cMode_ == 0)
{
fn_v_Link_AssertValidP(p_stLinkTable, _p_stPointer_);
fn_v_Mem_SetMode(_p_stPointer_->stHeader.ucMemLevel);
SCR_M_Mem_Free(_p_stPointer_->p_szKey);
}
},
_ucMin,
_ucMax
);
SCR_M_Hash_DeleteWithMemLevel
(
p_stLinkTable->a_stHashTableForValues,
_ucMin,
_ucMax
);
SCR_M_Hash_DeleteWithMemLevel
(
p_stLinkTable->a_stHashTableForKeys,
_ucMin,
_ucMax
);
uiPosTables++;
SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Table, uiPosTables, p_stLinkTable, SCR_g_st_Link_Array);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
}