home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
anwor032.zip
/
antiword.0.32
/
finddata.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-12-18
|
4KB
|
152 lines
/*
* finddata.c
* Copyright (C) 2000 A.J. van Os; Released under GPL
*
* Description:
* Find the blocks that contain the data of MS Word files
*/
#include <stdio.h>
#include <stdlib.h>
#include "antiword.h"
/*
* bAddDataBlocks - Add the blocks to the data block list
*
* Returns TRUE when successful, otherwise FALSE
*/
BOOL
bAddDataBlocks(long lFirstOffset, long lTotalLength,
long lStartBlock, const long *alBBD, size_t tBBDLen)
{
data_block_type tDataBlock;
long lDataOffset, lToGo, lOffset, lIndex;
BOOL bResult;
fail(lFirstOffset < 0);
fail(lStartBlock < 0);
fail(alBBD == NULL);
NO_DBG_HEX(lFirstOffset);
NO_DBG_DEC(tTotalLength);
lToGo = lTotalLength;
lDataOffset = lFirstOffset;
lOffset = lFirstOffset;
for (lIndex = lStartBlock;
lIndex != END_OF_CHAIN && lToGo > 0;
lIndex = alBBD[lIndex]) {
if (lIndex < 0 || lIndex >= (long)tBBDLen) {
werr(1, "The Big Block Depot is corrupt");
}
if (lOffset >= BIG_BLOCK_SIZE) {
lOffset -= BIG_BLOCK_SIZE;
continue;
}
tDataBlock.lFileOffset =
(lIndex + 1) * BIG_BLOCK_SIZE + lOffset;
tDataBlock.lDataOffset = lDataOffset;
tDataBlock.lLength = min(BIG_BLOCK_SIZE - lOffset, lToGo);
lOffset = 0;
if (!bAdd2DataBlockList(&tDataBlock)) {
DBG_HEX(tDataBlock.lFileOffset);
DBG_HEX(tDataBlock.lDataOffset);
DBG_DEC(tDataBlock.lLength);
return FALSE;
}
lDataOffset += tDataBlock.lLength;
lToGo -= tDataBlock.lLength;
}
bResult = lToGo == 0 ||
(lTotalLength == LONG_MAX && lIndex == END_OF_CHAIN);
DBG_DEC_C(!bResult, lToGo);
DBG_DEC_C(!bResult, lTotalLength);
DBG_DEC_C(!bResult, lIndex);
return bResult;
} /* end of bAddDataBlocks */
/*
* bGet6DocumentData - make a list of the data blocks of Word 6/7 files
*
* Code for "fast saved" files.
*
* Returns TRUE when successful, otherwise FALSE
*/
BOOL
bGet6DocumentData(FILE *pFile, long lStartBlock,
const long *alBBD, size_t tBBDLen, const unsigned char *aucHeader)
{
unsigned char *aucBuffer;
long lOffset, lTotLength, lBeginTextInfo;
size_t tTextInfoLen;
int iIndex;
int iOff, iType, iLen, iPieces;
DBG_MSG("bGet6DocumentData");
fail(pFile == NULL);
fail(alBBD == NULL);
fail(aucHeader == NULL);
lBeginTextInfo = (long)ulGetLong(0x160, aucHeader);
tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
DBG_HEX(lBeginTextInfo);
DBG_DEC(tTextInfoLen);
aucBuffer = xmalloc(tTextInfoLen);
if (!bReadBuffer(pFile, lStartBlock,
alBBD, tBBDLen, BIG_BLOCK_SIZE,
aucBuffer, lBeginTextInfo, tTextInfoLen)) {
aucBuffer = xfree(aucBuffer);
return FALSE;
}
NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
iOff = 0;
while (iOff < (int)tTextInfoLen) {
iType = (int)ucGetByte(iOff, aucBuffer);
iOff++;
if (iType == 0) {
iOff++;
continue;
}
iLen = (int)usGetWord(iOff, aucBuffer);
iOff += 2;
if (iType == 1) {
iOff += iLen;
continue;
}
if (iType != 2) {
werr(0, "Unknown type of 'fastsaved' format");
aucBuffer = xfree(aucBuffer);
return FALSE;
}
/* Type 2 */
NO_DBG_DEC(iLen);
iOff += 2;
iPieces = (iLen - 4) / 12;
DBG_DEC(iPieces);
for (iIndex = 0; iIndex < iPieces; iIndex++) {
lOffset = (long)ulGetLong(
iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
aucBuffer);
lTotLength = (long)ulGetLong(
iOff + (iIndex + 1) * 4,
aucBuffer) -
(long)ulGetLong(
iOff + iIndex * 4,
aucBuffer);
if (!bAddDataBlocks(lOffset, lTotLength,
lStartBlock,
alBBD, tBBDLen)) {
aucBuffer = xfree(aucBuffer);
return FALSE;
}
}
break;
}
aucBuffer = xfree(aucBuffer);
return TRUE;
} /* end of bGet6DocumentData */