📄 repll.c
字号:
Output: TRUE if the function should be called again, FALSE otherwise.
==========================================================================*/
BOOL REP_RemoveAllUnrefResources (void* pContext)
{
UINT16 iTemp=0;
UINT32 iId=0;
/* Find next element to remove */
while (((REPCONTEXT*)pContext)->iCurrentElement <
((REPCONTEXT*)pContext)->iNumberOfElements)
{
iTemp=((REPCONTEXT*)pContext)->iCurrentElement;
if (((REPCONTEXT*)pContext)->piResourceList[iTemp]!=0)
{
/* Remove from repository */
iId=((REPCONTEXT*)pContext)->piResourceList[iTemp];
Storage_DeleteBlock(&((REPCONTEXT*)pContext)->Storage,iId);
/* Remove from hash list */
((REPCONTEXT*)pContext)->piHashList[iTemp]=0;
((REPCONTEXT*)pContext)->iCurrentElement=(UINT16)(iTemp+1);
/* Continue */
return TRUE;
}
/* Check next */
((REPCONTEXT*)pContext)->iCurrentElement=(UINT16)(iTemp+1);
}
/* End */
return FALSE;
}
/*========================================================================
REP_TrimChannelList
==========================================================================
The function removes all 'id 0' from the piElementList and updates
the iNumberOfElements accordingly.
The function is called by REP_ScanRepository
Input: pContext (MUST be pREPCONTEXT)
Output: -
==========================================================================*/
void REP_TrimChannelList (void* pContext)
{
UINT16 iNbrCh=0;
UINT16 iCount=0;
UINT16 iStoreIndex=0;
UINT32 *piNewList=NULL;
/* Count channels (not 0) */
while (iCount<((REPCONTEXT*)pContext)->iNumberOfElements)
{
if (((REPCONTEXT*)pContext)->piElementList[iCount]!=0)
{
iNbrCh++;
}
iCount++;
}
/* Create new resource list */
piNewList=NEWARRAY(UINT32,iNbrCh);
iCount=0;
/* Copy all 'not 0'-id:s to new list */
while (iCount<((REPCONTEXT*)pContext)->iNumberOfElements)
{
if (((REPCONTEXT*)pContext)->piElementList[iCount]!=0)
{
/* Store channel id */
piNewList[iStoreIndex]=((REPCONTEXT*)pContext)
->piElementList[iCount];
iStoreIndex++;
}
iCount++;
}
/* Dealloc old list */
DEALLOC(&((REPCONTEXT*)pContext)->piElementList);
/* Store new list and element counter */
((REPCONTEXT*)pContext)->piElementList=piNewList;
((REPCONTEXT*)pContext)->iNumberOfElements=iNbrCh;
}
/*========================================================================
REP_TrimResourceList
==========================================================================
The function removes all 'id 0' from the piResourceList and updates
the piResourceCounter accordingly.
The function is called by REP_ScanRepository
Input: pContext (MUST be pREPCONTEXT)
Output: -
==========================================================================*/
void REP_TrimResourceList (void* pContext)
{
UINT16 iNbrRes=0;
UINT16 iCount=0;
UINT16 iStoreIndex=0;
UINT32 *piNewList=NULL;
/* Count resources (not 0) */
while (iCount<((REPCONTEXT*)pContext)->iNumberOfElements)
{
if (((REPCONTEXT*)pContext)->piResourceList[iCount]!=0)
{
iNbrRes++;
}
iCount++;
}
/* Create new resource list */
piNewList=NEWARRAY(UINT32,iNbrRes);
iCount=0;
/* Copy all 'not 0'-id:s to new list */
while (iCount<((REPCONTEXT*)pContext)->iNumberOfElements)
{
if (((REPCONTEXT*)pContext)->piResourceList[iCount]!=0)
{
/* Store resource id */
piNewList[iStoreIndex]=((REPCONTEXT*)pContext)
->piResourceList[iCount];
iStoreIndex++;
}
iCount++;
}
/* Dealloc old list */
DEALLOC(&((REPCONTEXT*)pContext)->piResourceList);
/* Store new list and resource counter */
((REPCONTEXT*)pContext)->piResourceList=piNewList;
((REPCONTEXT*)pContext)->iNumberOfResources=iNbrRes;
}
/*========================================================================
REP_CalculateHashValues
==========================================================================
The function calculates hash values for all resources in the
piResourceList. The values are stored in the piHashList. The function
should be called repeatedly until it returns FALSE.
Note! The piHashList is created in this function. The function uses
the iCurrentElement to keep track of the next resource to calculate
hash value for.
The function is called by REP_ScanRepository
Input: pContext (MUST be pREPCONTEXT)
Output: TRUE if the function should be called again, FALSE otherwise.
==========================================================================*/
BOOL REP_CalculateHashValues (void* pContext)
{
UINT32 iHashValue=0;
UINT32 *piHashList=NULL;
BYTE* pbUrl=NULL;
/* Check if any resources */
if (((REPCONTEXT*)pContext)->iNumberOfResources!=0)
{
/* Check if first time */
if (((REPCONTEXT*)pContext)->iCurrentElement==0)
{
/* Create hash list */
piHashList=NEWARRAY(UINT32,((REPCONTEXT*)pContext)
->iNumberOfResources);
/* Store in context */
((REPCONTEXT*)pContext)->piHashList=piHashList;
}
/* Calculate hash value and store */
if (((REPCONTEXT*)pContext)->iCurrentElement<
((REPCONTEXT*)pContext)->iNumberOfResources)
{
/* Get url */
pbUrl=REP_GetResourceUrl (pContext,((REPCONTEXT*)pContext)->
piResourceList[((REPCONTEXT*)pContext)->iCurrentElement]);
if (pbUrl!=NULL)
{
/* Calculate Hash value */
if (b_HashURL (pbUrl, &iHashValue))
{
/* Store hash value */
((REPCONTEXT*)pContext)->piHashList
[((REPCONTEXT*)pContext)->iCurrentElement]=iHashValue;
}
else
{
/* Error - Store 0 as hash value */
((REPCONTEXT*)pContext)->piHashList
[((REPCONTEXT*)pContext)->iCurrentElement]=0;
}
DEALLOC(&pbUrl);
}
else
{
/* Error - store 0 as hash value */
((REPCONTEXT*)pContext)->piHashList
[((REPCONTEXT*)pContext)->iCurrentElement]=0;
}
/* Get next resource */
((REPCONTEXT*)pContext)->iCurrentElement++;
return TRUE;
}
}
/* End */
return FALSE;
}
/*========================================================================
REP_RemoveResFromList
==========================================================================
The function removes (replaces with 0) the repository id from the
piResourceList during a repository scan.
The function is called by REP_PutChannelInSDLList
Input: pContext (MUST be pREPCONTEXT) and Resource Id
Output: -
==========================================================================*/
void REP_RemoveResFromList (void* pContext, UINT32 iResourceId)
{
UINT16 iCount=0;
while (iCount<((REPCONTEXT*)pContext)->iNumberOfElements)
{
if (((REPCONTEXT*)pContext)->piResourceList[iCount]==iResourceId)
{
((REPCONTEXT*)pContext)->piResourceList[iCount]=0;
return;
}
iCount++;
}
}
/*========================================================================
REP_PutChannelInSDLList
==========================================================================
NOTE! The current implementation does NOT return channels that are
*installing*. These channels are instead removed along with their
resources. This migth be subject to change.
The function reads a channel from the repository and stores the data
in a SDL-list. If the channel could not be found or if it is corrupt,
FALSE is returned. Otherwise TRUE is returned. The function also does
a status check (expiry date and status). If the channel is too old or
if its status is NOT *active*, it is NOT added to the list (TRUE is
however still returned in this case - not an error).
The function is called by REP_ScanRepository and REP_GetAllChannels.
If the function is called from REP_ScanRepository, the fScan parameter
should be set to TRUE. If it is set, the function will increase the
referring counter (install counter if status on channel is installing)
by one on every associated resource. Also, all resources that are
requested are removed from the piResourceList (replaced with 0).
The function is called by REP_ScanRepository and REP_GetAllChannels
Input: pContext (MUST be pREPCONTEXT), Channel id, and pointer to
ContentList, fScan (TRUE if called from REP_ScanRepository,
FALSE otherwise)
Output: TRUE/FALSE
==========================================================================*/
BOOL REP_PutChannelInSDLList (void* pContext, UINT32 iChannelID,
void* pContentList, BOOL fScan, UINT32 iTime)
{
pREPCHSTRUCT pChElm=NULL;
pREPCONTENTSTRUCT pChannel=NULL;
UINT8 iCount=0;
/* Get channel with id */
pChannel=REP_GetContentWithID(pContext,iChannelID,CONTENTTYPE_CHANNEL);
if (pChannel!=NULL)
{
/* Check status and expiry date */
if ( ((pChannel->content.pChContentStruct->iExpiryDate !=0 ) &&
(pChannel->content.pChContentStruct->iExpiryDate < iTime)) ||
(pChannel->content.pChContentStruct->iStatus == CONTENT_STALE))
{
/* Channel to old, remove */
if (fScan)
{
/* No root block yet - remove channel but do not
change resource counters. */
Storage_DeleteBlock(&((REPCONTEXT*)pContext)->Storage,
iChannelID);
}
else
{
/* Remove channel and update root block accordingly */
if (!REP_DeleteChannel (pContext, iChannelID))
{
/* Something is very wrong. */
REP_ChangeRootBlockStatus (pContext,REPROOT_STATUS_CORRUPT);
}
}
}
else
{
/* Create new REPCHSTRUCT */
pChElm=NEWSTRUCT(REPCHSTRUCT);
/* Move fields from pREPCONTENTSTRUCT */
pChElm->iStatus=pChannel->content.pChContentStruct->iStatus;
pChElm->pchEventId=pChannel->content.pChContentStruct->pwchEventId;
pChannel->content.pChContentStruct->pwchEventId=NULL;
pChElm->pchchannelid=pChannel->content.pChContentStruct->pwchchannelid;
pChannel->content.pChContentStruct->pwchchannelid=NULL;
pChElm->iLLRepHId=pChannel->iId;
if (pChannel->content.pChContentStruct->piAllResInChList!=NULL)
{
pChElm->iLLRepHIdToFirstRes=
*(pChannel->content.pChContentStruct->piAllResInChList);
}
else
{
pChElm->iLLRepHIdToFirstRes=0;
}
if (fScan)
{
/* Change resource status on all associated resources. */
while (iCount<pChannel->content.pChContentStruct->iResCounter)
{
if (pChannel->content.pChContentStruct->iStatus==CONTENT_ACTIVE)
{
/* Active */
REP_ChangeResourceStatus(pContext,pChannel->content.
pChContentStruct->piAllResInChList[iCount],0,1);
/* Remove resource from piResourceList - all resources that are
NOT removed from this list is removed from the repository in
PHASE 4 in the REP_ScanRepository function. */
REP_RemoveResFromList (pContext,pChannel->content.
pChContentStruct->piAllResInChList[iCount]);
}
/* else
{
... THIS PART IS USED IF INSTALLATION SHOULD BE ABLE TO CONTINUE
EVEN IF THE GWC HAS BEEN RESTARTED.
*/
/* Installing
REP_ChangeResourceStatus(pContext,pChannel->content.
pChContentStruct->piAllResInChList[iCount],1,0);
}
*/
/* Next resource */
iCount++;
}
}
}
/* Add channel to list IF IT IS ACTIVE */
if (pChannel->content.pChContentStruct->iStatus==CONTENT_ACTIVE)
{
SDL_AddListElement(pContentList,0,0,pChElm);
}
/* Delete pREPCONTENTSTRUCT */
Free_RepContent(pChannel);
return TRUE;
}
return FALSE;
}
/*========================================================================
==========================================================================
EXTERNAL FUNCTIONS
==========================================================================
=========================================================================*/
/*========================================================================
REP_GetResourceWithUrl
=========================================================================*/
pREPCONTENTSTRUCT REP_GetResourceWithUrl (void* pContext, BYTE *pbUrl,
BOOL fInstall)
{
BOOL fFound=FALSE;
UINT32 iTempID=0;
UINT32 iHashValue=0;
UINT16 iCurRes=0;
pREPCONTENTSTRUCT pResource=NULL;
if (pbUrl!=NULL)
{
/* Calculate Hash value */
if (b_HashURL (pbUrl, &iHashValue))
{
/* For all resources, do */
while ((iCurRes<((pREPCONTEXT)(pContext))
->iNumberOfResources)&&(!fFound))
{
iTempID=((pREPCONTEXT)(pContext))->piResourceList[iCurRes];
/* Check if hash values are equal */
if (iHashValue==((pREPCONTEXT)(pContext))->piHashList[iCurRes])
{
/* Hash values equal, compare url:s */
fFound=REP_CompareUrl(pContext,pbUrl,iTempID);
}
/* Next in list */
iCurRes++;
}
}
else
{
/* Error in hashing - find in traditional way */
while ((iCurRes<((pREPCONTEXT)(pContext))
->iNumberOfResources)&&(!fFound))
{
iTempID=((pREPCONTEXT)(pContext))->piResourceList[iCurRes];
/* Compare url:s */
fFound=REP_CompareUrl(pContext,pbUrl,iTempID);
/* Next in list */
iCurRes++;
}
}
if (fFound)
{
/* Get the content */
pResource=REP_GetContentWithID(pContext,iTempID,
CONTENTTYPE_RESOURCE);
if ((pResource!=NULL)&&(fInstall))
{
/* Change the install counter (+1) on the resource and change
the state of the accordingly. */
if (REP_ChangeResourceStatus(pContext,iTempID,1,0))
{
/* Add one to install counter in the copy */
pResource->content.pResContentStruct->iInstallCounter++;
}
else
{
/* Could not change status add resource to tMODIFYROOT list
in context with action RESOURCE_REMOVE */
REP_AddToModifyRoot (pContext,iTempID,
RESOURCE_REMOVE,iHashValue);
}
}
}
}
return pResource;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -