/* *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * 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); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ }