mirror of
https://github.com/simon987/antiword.git
synced 2025-04-10 13:06:41 +00:00
115 lines
2.7 KiB
C
115 lines
2.7 KiB
C
/*
|
|
* depot.c
|
|
* Copyright (C) 1998-2002 A.J. van Os; Released under GPL
|
|
*
|
|
* Description:
|
|
* Functions to compute the depot offset
|
|
*/
|
|
|
|
#include "antiword.h"
|
|
|
|
#define SIZE_RATIO (BIG_BLOCK_SIZE/SMALL_BLOCK_SIZE)
|
|
|
|
static ULONG *aulSmallBlockList = NULL;
|
|
static size_t tSmallBlockListLen = 0;
|
|
|
|
|
|
/*
|
|
* vDestroySmallBlockList - destroy the small block list
|
|
*/
|
|
void
|
|
vDestroySmallBlockList(void)
|
|
{
|
|
DBG_MSG("vDestroySmallBlockList");
|
|
|
|
aulSmallBlockList = xfree(aulSmallBlockList);
|
|
tSmallBlockListLen = 0;
|
|
} /* end of vDestroySmalBlockList */
|
|
|
|
/*
|
|
* vCreateSmallBlockList - create the small block list
|
|
*
|
|
* returns: TRUE when successful, otherwise FALSE
|
|
*/
|
|
BOOL
|
|
bCreateSmallBlockList(ULONG ulStartblock, const ULONG *aulBBD, size_t tBBDLen)
|
|
{
|
|
ULONG ulTmp;
|
|
size_t tSize;
|
|
int iIndex;
|
|
|
|
fail(aulSmallBlockList != NULL);
|
|
fail(tSmallBlockListLen != 0);
|
|
fail(ulStartblock > MAX_BLOCKNUMBER && ulStartblock != END_OF_CHAIN);
|
|
fail(aulBBD == NULL);
|
|
fail(tBBDLen == 0);
|
|
|
|
/* Find the length of the small block list */
|
|
for (tSmallBlockListLen = 0, ulTmp = ulStartblock;
|
|
tSmallBlockListLen < tBBDLen && ulTmp != END_OF_CHAIN;
|
|
tSmallBlockListLen++, ulTmp = aulBBD[ulTmp]) {
|
|
if (ulTmp >= (ULONG)tBBDLen) {
|
|
DBG_DEC(ulTmp);
|
|
DBG_DEC(tBBDLen);
|
|
werr(1, "The Big Block Depot is damaged");
|
|
}
|
|
}
|
|
DBG_DEC(tSmallBlockListLen);
|
|
|
|
if (tSmallBlockListLen == 0) {
|
|
/* There is no small block list */
|
|
fail(ulStartblock != END_OF_CHAIN);
|
|
aulSmallBlockList = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
/* Create the small block list */
|
|
tSize = tSmallBlockListLen * sizeof(ULONG);
|
|
aulSmallBlockList = xmalloc(tSize);
|
|
for (iIndex = 0, ulTmp = ulStartblock;
|
|
iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN;
|
|
iIndex++, ulTmp = aulBBD[ulTmp]) {
|
|
if (ulTmp >= (ULONG)tBBDLen) {
|
|
DBG_DEC(ulTmp);
|
|
DBG_DEC(tBBDLen);
|
|
werr(1, "The Big Block Depot is damaged");
|
|
}
|
|
aulSmallBlockList[iIndex] = ulTmp;
|
|
NO_DBG_DEC(aulSmallBlockList[iIndex]);
|
|
}
|
|
return TRUE;
|
|
} /* end of bCreateSmallBlockList */
|
|
|
|
/*
|
|
* ulDepotOffset - get the depot offset the block list
|
|
*/
|
|
ULONG
|
|
ulDepotOffset(ULONG ulIndex, size_t tBlockSize)
|
|
{
|
|
ULONG ulTmp;
|
|
size_t tTmp;
|
|
|
|
fail(ulIndex >= ULONG_MAX / BIG_BLOCK_SIZE);
|
|
|
|
switch (tBlockSize) {
|
|
case BIG_BLOCK_SIZE:
|
|
return (ulIndex + 1) * BIG_BLOCK_SIZE;
|
|
case SMALL_BLOCK_SIZE:
|
|
tTmp = (size_t)(ulIndex / SIZE_RATIO);
|
|
ulTmp = ulIndex % SIZE_RATIO;
|
|
if (aulSmallBlockList == NULL ||
|
|
tTmp >= tSmallBlockListLen) {
|
|
DBG_HEX(aulSmallBlockList);
|
|
DBG_DEC(tSmallBlockListLen);
|
|
DBG_DEC(tTmp);
|
|
return 0;
|
|
}
|
|
return ((aulSmallBlockList[tTmp] + 1) * SIZE_RATIO +
|
|
ulTmp) * SMALL_BLOCK_SIZE;
|
|
default:
|
|
DBG_DEC(tBlockSize);
|
|
DBG_FIXME();
|
|
return 0;
|
|
}
|
|
} /* end of ulDepotOffset */
|