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 >
C/C++ Source or Header  |  2000-12-18  |  4KB  |  152 lines

  1. /*
  2.  * finddata.c
  3.  * Copyright (C) 2000 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Find the blocks that contain the data of MS Word files
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include "antiword.h"
  12.  
  13.  
  14. /*
  15.  * bAddDataBlocks - Add the blocks to the data block list
  16.  *
  17.  * Returns TRUE when successful, otherwise FALSE
  18.  */
  19. BOOL
  20. bAddDataBlocks(long lFirstOffset, long lTotalLength,
  21.     long lStartBlock, const long *alBBD, size_t tBBDLen)
  22. {
  23.     data_block_type    tDataBlock;
  24.     long    lDataOffset, lToGo, lOffset, lIndex;
  25.     BOOL    bResult;
  26.  
  27.     fail(lFirstOffset < 0);
  28.     fail(lStartBlock < 0);
  29.     fail(alBBD == NULL);
  30.  
  31.     NO_DBG_HEX(lFirstOffset);
  32.     NO_DBG_DEC(tTotalLength);
  33.  
  34.     lToGo = lTotalLength;
  35.     lDataOffset = lFirstOffset;
  36.     lOffset = lFirstOffset;
  37.     for (lIndex = lStartBlock;
  38.          lIndex != END_OF_CHAIN && lToGo > 0;
  39.          lIndex = alBBD[lIndex]) {
  40.         if (lIndex < 0 || lIndex >= (long)tBBDLen) {
  41.             werr(1, "The Big Block Depot is corrupt");
  42.         }
  43.         if (lOffset >= BIG_BLOCK_SIZE) {
  44.             lOffset -= BIG_BLOCK_SIZE;
  45.             continue;
  46.         }
  47.         tDataBlock.lFileOffset =
  48.             (lIndex + 1) * BIG_BLOCK_SIZE + lOffset;
  49.         tDataBlock.lDataOffset = lDataOffset;
  50.         tDataBlock.lLength = min(BIG_BLOCK_SIZE - lOffset, lToGo);
  51.         lOffset = 0;
  52.         if (!bAdd2DataBlockList(&tDataBlock)) {
  53.             DBG_HEX(tDataBlock.lFileOffset);
  54.             DBG_HEX(tDataBlock.lDataOffset);
  55.             DBG_DEC(tDataBlock.lLength);
  56.             return FALSE;
  57.         }
  58.         lDataOffset += tDataBlock.lLength;
  59.         lToGo -= tDataBlock.lLength;
  60.     }
  61.     bResult = lToGo == 0 ||
  62.         (lTotalLength == LONG_MAX && lIndex == END_OF_CHAIN);
  63.     DBG_DEC_C(!bResult, lToGo);
  64.     DBG_DEC_C(!bResult, lTotalLength);
  65.     DBG_DEC_C(!bResult, lIndex);
  66.     return bResult;
  67. } /* end of bAddDataBlocks */
  68.  
  69. /*
  70.  * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
  71.  *
  72.  * Code for "fast saved" files.
  73.  *
  74.  * Returns TRUE when successful, otherwise FALSE
  75.  */
  76. BOOL
  77. bGet6DocumentData(FILE *pFile, long lStartBlock,
  78.     const long *alBBD, size_t tBBDLen, const unsigned char *aucHeader)
  79. {
  80.     unsigned char    *aucBuffer;
  81.     long    lOffset, lTotLength, lBeginTextInfo;
  82.     size_t    tTextInfoLen;
  83.     int    iIndex;
  84.     int    iOff, iType, iLen, iPieces;
  85.  
  86.     DBG_MSG("bGet6DocumentData");
  87.  
  88.     fail(pFile == NULL);
  89.     fail(alBBD == NULL);
  90.     fail(aucHeader == NULL);
  91.  
  92.     lBeginTextInfo = (long)ulGetLong(0x160, aucHeader);
  93.     tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
  94.     DBG_HEX(lBeginTextInfo);
  95.     DBG_DEC(tTextInfoLen);
  96.  
  97.     aucBuffer = xmalloc(tTextInfoLen);
  98.     if (!bReadBuffer(pFile, lStartBlock,
  99.             alBBD, tBBDLen, BIG_BLOCK_SIZE,
  100.             aucBuffer, lBeginTextInfo, tTextInfoLen)) {
  101.         aucBuffer = xfree(aucBuffer);
  102.         return FALSE;
  103.     }
  104.     NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
  105.  
  106.     iOff = 0;
  107.     while (iOff < (int)tTextInfoLen) {
  108.         iType = (int)ucGetByte(iOff, aucBuffer);
  109.         iOff++;
  110.         if (iType == 0) {
  111.             iOff++;
  112.             continue;
  113.         }
  114.         iLen = (int)usGetWord(iOff, aucBuffer);
  115.         iOff += 2;
  116.         if (iType == 1) {
  117.             iOff += iLen;
  118.             continue;
  119.         }
  120.         if (iType != 2) {
  121.             werr(0, "Unknown type of 'fastsaved' format");
  122.             aucBuffer = xfree(aucBuffer);
  123.             return FALSE;
  124.         }
  125.         /* Type 2 */
  126.         NO_DBG_DEC(iLen);
  127.         iOff += 2;
  128.         iPieces = (iLen - 4) / 12;
  129.         DBG_DEC(iPieces);
  130.         for (iIndex = 0; iIndex < iPieces; iIndex++) {
  131.             lOffset = (long)ulGetLong(
  132.                 iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
  133.                 aucBuffer);
  134.             lTotLength = (long)ulGetLong(
  135.                         iOff + (iIndex + 1) * 4,
  136.                         aucBuffer) -
  137.                     (long)ulGetLong(
  138.                         iOff + iIndex * 4,
  139.                         aucBuffer);
  140.             if (!bAddDataBlocks(lOffset, lTotLength,
  141.                     lStartBlock,
  142.                     alBBD, tBBDLen)) {
  143.                 aucBuffer = xfree(aucBuffer);
  144.                 return FALSE;
  145.             }
  146.         }
  147.         break;
  148.     }
  149.     aucBuffer = xfree(aucBuffer);
  150.     return TRUE;
  151. } /* end of bGet6DocumentData */
  152.