home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / notes.c < prev    next >
C/C++ Source or Header  |  2000-12-18  |  11KB  |  396 lines

  1. /*
  2.  * notes.c
  3.  * Copyright (C) 1998-2000 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Functions to tell the difference between footnotes and endnotes
  7.  */
  8.  
  9. #include "antiword.h"
  10.  
  11. /* Variables needed to write the Footnote and Endnote Lists */
  12. static long    *alFootnoteList = NULL;
  13. static size_t    tFootnoteListLength = 0;
  14. static long    *alEndnoteList = NULL;
  15. static size_t    tEndnoteListLength = 0;
  16.  
  17.  
  18. /*
  19.  * Destroy the lists with footnote and endnote information
  20.  */
  21. void
  22. vDestroyNotesInfoLists(void)
  23. {
  24.     DBG_MSG("vDestroyNotesInfoLists");
  25.  
  26.     /* Free the lists and reset all control variables */
  27.     alEndnoteList = xfree(alEndnoteList);
  28.     alFootnoteList = xfree(alFootnoteList);
  29.     tEndnoteListLength = 0;
  30.     tFootnoteListLength = 0;
  31. } /* end of vDestroyNotesInfoLists */
  32.  
  33. /*
  34.  * Build the list with footnote information for Word 6/7 files
  35.  */
  36. static void
  37. vGet6FootnotesInfo(FILE *pFile, long lStartBlock,
  38.     const long *alBBD, size_t tBBDLen,
  39.     const unsigned char *aucHeader)
  40. {
  41.     unsigned char    *aucBuffer;
  42.     long    lFileOffset, lBeginOfText, lOffset, lBeginFootnoteInfo;
  43.     size_t    tFootnoteInfoLen;
  44.     int    iIndex;
  45.  
  46.     fail(pFile == NULL || aucHeader == NULL);
  47.     fail(lStartBlock < 0);
  48.     fail(alBBD == NULL);
  49.  
  50.     lBeginOfText = (long)ulGetLong(0x18, aucHeader);
  51.     DBG_HEX(lBeginOfText);
  52.     lBeginFootnoteInfo = (long)ulGetLong(0x68, aucHeader);
  53.     DBG_HEX(lBeginFootnoteInfo);
  54.     tFootnoteInfoLen = (size_t)ulGetLong(0x6c, aucHeader);
  55.     DBG_DEC(tFootnoteInfoLen);
  56.  
  57.     if (tFootnoteInfoLen < 10) {
  58.         DBG_MSG("No Footnotes in this document");
  59.         return;
  60.     }
  61.  
  62.     aucBuffer = xmalloc(tFootnoteInfoLen);
  63.     if (!bReadBuffer(pFile, lStartBlock,
  64.             alBBD, tBBDLen, BIG_BLOCK_SIZE,
  65.             aucBuffer, lBeginFootnoteInfo, tFootnoteInfoLen)) {
  66.         aucBuffer = xfree(aucBuffer);
  67.         return;
  68.     }
  69.     NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
  70.  
  71.     fail(tFootnoteListLength != 0);
  72.     tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
  73.     fail(tFootnoteListLength == 0);
  74.  
  75.     fail(alFootnoteList != NULL);
  76.     alFootnoteList = xmalloc(sizeof(long) * tFootnoteListLength);
  77.  
  78.     for (iIndex = 0; iIndex < (int)tFootnoteListLength; iIndex++) {
  79.         lOffset = (long)ulGetLong(iIndex * 4, aucBuffer);
  80.         DBG_HEX(lOffset);
  81.         lFileOffset = lTextOffset2FileOffset(lBeginOfText + lOffset);
  82.         DBG_HEX(lFileOffset);
  83.         alFootnoteList[iIndex] = lFileOffset;
  84.     }
  85.     aucBuffer = xfree(aucBuffer);
  86. } /* end of vGet6FootnotesInfo */
  87.  
  88. /*
  89.  * Build the list with endnote information for Word 6/7 files
  90.  */
  91. static void
  92. vGet6EndnotesInfo(FILE *pFile, long lStartBlock,
  93.     const long *alBBD, size_t tBBDLen,
  94.     const unsigned char *aucHeader)
  95. {
  96.     unsigned char    *aucBuffer;
  97.     long    lFileOffset, lBeginOfText, lOffset, lBeginEndnoteInfo;
  98.     size_t    tEndnoteInfoLen;
  99.     int    iIndex;
  100.  
  101.     fail(pFile == NULL || aucHeader == NULL);
  102.     fail(lStartBlock < 0);
  103.     fail(alBBD == NULL);
  104.  
  105.     lBeginOfText = (long)ulGetLong(0x18, aucHeader);
  106.     DBG_HEX(lBeginOfText);
  107.     lBeginEndnoteInfo = (long)ulGetLong(0x1d2, aucHeader);
  108.     DBG_HEX(lBeginEndnoteInfo);
  109.     tEndnoteInfoLen = (size_t)ulGetLong(0x1d6, aucHeader);
  110.     DBG_DEC(tEndnoteInfoLen);
  111.  
  112.     if (tEndnoteInfoLen < 10) {
  113.         DBG_MSG("No Endnotes in this document");
  114.         return;
  115.     }
  116.  
  117.     aucBuffer = xmalloc(tEndnoteInfoLen);
  118.     if (!bReadBuffer(pFile, lStartBlock,
  119.             alBBD, tBBDLen, BIG_BLOCK_SIZE,
  120.             aucBuffer, lBeginEndnoteInfo, tEndnoteInfoLen)) {
  121.         aucBuffer = xfree(aucBuffer);
  122.         return;
  123.     }
  124.     NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
  125.  
  126.     fail(tEndnoteListLength != 0);
  127.     tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
  128.     fail(tEndnoteListLength == 0);
  129.  
  130.     fail(alEndnoteList != NULL);
  131.     alEndnoteList = xmalloc(sizeof(long) * tEndnoteListLength);
  132.  
  133.     for (iIndex = 0; iIndex < (int)tEndnoteListLength; iIndex++) {
  134.         lOffset = (long)ulGetLong(iIndex * 4, aucBuffer);
  135.         DBG_HEX(lOffset);
  136.         lFileOffset = lTextOffset2FileOffset(lBeginOfText + lOffset);
  137.         DBG_HEX(lFileOffset);
  138.         alEndnoteList[iIndex] = lFileOffset;
  139.     }
  140.     aucBuffer = xfree(aucBuffer);
  141. } /* end of vGet6EndnotesInfo */
  142.  
  143. /*
  144.  * Build the lists note information for Word 6/7 files
  145.  */
  146. static void
  147. vGet6NotesInfo(FILE *pFile, long lStartBlock,
  148.     const long *alBBD, size_t tBBDLen,
  149.     const unsigned char *aucHeader)
  150. {
  151.     vGet6FootnotesInfo(pFile, lStartBlock,
  152.             alBBD, tBBDLen, aucHeader);
  153.     vGet6EndnotesInfo(pFile, lStartBlock,
  154.             alBBD, tBBDLen, aucHeader);
  155. } /* end of vGet6NotesInfo */
  156.  
  157. /*
  158.  * Build the list with footnote information for Word 8/97 files
  159.  */
  160. static void
  161. vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
  162.     const long *alBBD, size_t tBBDLen, const long *alSBD, size_t tSBDLen,
  163.     const unsigned char *aucHeader)
  164. {
  165.     const long    *alBlockDepot;
  166.     unsigned char    *aucBuffer;
  167.     long    lFileOffset, lBeginOfText, lOffset;
  168.     long    lBeginFootnoteInfo, lTableSize, lTableStartBlock;
  169.     size_t    tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
  170.     int    iIndex;
  171.     unsigned short    usDocStatus;
  172.  
  173.     lBeginOfText = (long)ulGetLong(0x18, aucHeader);
  174.     DBG_HEX(lBeginOfText);
  175.     lBeginFootnoteInfo = (long)ulGetLong(0xaa, aucHeader);
  176.     DBG_HEX(lBeginFootnoteInfo);
  177.     tFootnoteInfoLen = (size_t)ulGetLong(0xae, aucHeader);
  178.     DBG_DEC(tFootnoteInfoLen);
  179.  
  180.     if (tFootnoteInfoLen < 10) {
  181.         DBG_MSG("No Footnotes in this document");
  182.         return;
  183.     }
  184.  
  185.     /* Use 0Table or 1Table? */
  186.     usDocStatus = usGetWord(0x0a, aucHeader);
  187.     if (usDocStatus & BIT(9)) {
  188.         lTableStartBlock = pPPS->t1Table.lSb;
  189.         lTableSize = pPPS->t1Table.lSize;
  190.     } else {
  191.         lTableStartBlock = pPPS->t0Table.lSb;
  192.         lTableSize = pPPS->t0Table.lSize;
  193.     }
  194.     DBG_DEC(lTableStartBlock);
  195.     if (lTableStartBlock < 0) {
  196.         DBG_DEC(lTableStartBlock);
  197.         DBG_MSG("No notes information");
  198.         return;
  199.     }
  200.     DBG_HEX(lTableSize);
  201.     if (lTableSize < MIN_SIZE_FOR_BBD_USE) {
  202.           /* Use the Small Block Depot */
  203.         alBlockDepot = alSBD;
  204.         tBlockDepotLen = tSBDLen;
  205.         tBlockSize = SMALL_BLOCK_SIZE;
  206.     } else {
  207.           /* Use the Big Block Depot */
  208.         alBlockDepot = alBBD;
  209.         tBlockDepotLen = tBBDLen;
  210.         tBlockSize = BIG_BLOCK_SIZE;
  211.     }
  212.     aucBuffer = xmalloc(tFootnoteInfoLen);
  213.     if (!bReadBuffer(pFile, lTableStartBlock,
  214.             alBlockDepot, tBlockDepotLen, tBlockSize,
  215.             aucBuffer, lBeginFootnoteInfo, tFootnoteInfoLen)) {
  216.         aucBuffer = xfree(aucBuffer);
  217.         return;
  218.     }
  219.     NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
  220.  
  221.     fail(tFootnoteListLength != 0);
  222.     tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
  223.     fail(tFootnoteListLength == 0);
  224.  
  225.     fail(alFootnoteList != NULL);
  226.     alFootnoteList = xmalloc(sizeof(long) * tFootnoteListLength);
  227.  
  228.     for (iIndex = 0; iIndex < (int)tFootnoteListLength; iIndex++) {
  229.         lOffset = (long)ulGetLong(iIndex * 4, aucBuffer);
  230.         DBG_HEX(lOffset);
  231.         lFileOffset = lTextOffset2FileOffset(lBeginOfText + lOffset);
  232.         DBG_HEX(lFileOffset);
  233.         alFootnoteList[iIndex] = lFileOffset;
  234.     }
  235.     aucBuffer = xfree(aucBuffer);
  236. } /* end of vGet8FootnotesInfo */
  237.  
  238. /*
  239.  * Build the list with endnote information for Word 8/97 files
  240.  */
  241. static void
  242. vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
  243.     const long *alBBD, size_t tBBDLen, const long *alSBD, size_t tSBDLen,
  244.     const unsigned char *aucHeader)
  245. {
  246.     const long    *alBlockDepot;
  247.     unsigned char    *aucBuffer;
  248.     long    lFileOffset, lBeginOfText, lOffset;
  249.     long    lBeginEndnoteInfo, lTableSize, lTableStartBlock;
  250.     size_t    tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
  251.     int    iIndex;
  252.     unsigned short    usDocStatus;
  253.  
  254.     lBeginOfText = (long)ulGetLong(0x18, aucHeader);
  255.     DBG_HEX(lBeginOfText);
  256.     lBeginEndnoteInfo = (long)ulGetLong(0x20a, aucHeader);
  257.     DBG_HEX(lBeginEndnoteInfo);
  258.     tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader);
  259.     DBG_DEC(tEndnoteInfoLen);
  260.  
  261.     if (tEndnoteInfoLen < 10) {
  262.         DBG_MSG("No Endnotes in this document");
  263.         return;
  264.     }
  265.  
  266.     /* Use 0Table or 1Table? */
  267.     usDocStatus = usGetWord(0x0a, aucHeader);
  268.     if (usDocStatus & BIT(9)) {
  269.         lTableStartBlock = pPPS->t1Table.lSb;
  270.         lTableSize = pPPS->t1Table.lSize;
  271.     } else {
  272.         lTableStartBlock = pPPS->t0Table.lSb;
  273.         lTableSize = pPPS->t0Table.lSize;
  274.     }
  275.     DBG_DEC(lTableStartBlock);
  276.     if (lTableStartBlock < 0) {
  277.         DBG_DEC(lTableStartBlock);
  278.         DBG_MSG("No notes information");
  279.         return;
  280.     }
  281.     DBG_HEX(lTableSize);
  282.     if (lTableSize < MIN_SIZE_FOR_BBD_USE) {
  283.           /* Use the Small Block Depot */
  284.         alBlockDepot = alSBD;
  285.         tBlockDepotLen = tSBDLen;
  286.         tBlockSize = SMALL_BLOCK_SIZE;
  287.     } else {
  288.           /* Use the Big Block Depot */
  289.         alBlockDepot = alBBD;
  290.         tBlockDepotLen = tBBDLen;
  291.         tBlockSize = BIG_BLOCK_SIZE;
  292.     }
  293.     aucBuffer = xmalloc(tEndnoteInfoLen);
  294.     if (!bReadBuffer(pFile, lTableStartBlock,
  295.             alBlockDepot, tBlockDepotLen, tBlockSize,
  296.             aucBuffer, lBeginEndnoteInfo, tEndnoteInfoLen)) {
  297.         aucBuffer = xfree(aucBuffer);
  298.         return;
  299.     }
  300.     DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
  301.  
  302.     fail(tEndnoteListLength != 0);
  303.     tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
  304.     fail(tEndnoteListLength == 0);
  305.  
  306.     fail(alEndnoteList != NULL);
  307.     alEndnoteList = xmalloc(sizeof(long) * tEndnoteListLength);
  308.  
  309.     for (iIndex = 0; iIndex < (int)tEndnoteListLength; iIndex++) {
  310.         lOffset = (long)ulGetLong(iIndex * 4, aucBuffer);
  311.         DBG_HEX(lOffset);
  312.         lFileOffset = lTextOffset2FileOffset(lBeginOfText + lOffset);
  313.         DBG_HEX(lFileOffset);
  314.         alEndnoteList[iIndex] = lFileOffset;
  315.     }
  316.     aucBuffer = xfree(aucBuffer);
  317. } /* end of vGet8EndnotesInfo */
  318.  
  319. /*
  320.  * Build the lists with footnote and endnote information for Word 8/97 files
  321.  */
  322. static void
  323. vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
  324.     const long *alBBD, size_t tBBDLen, const long *alSBD, size_t tSBDLen,
  325.     const unsigned char *aucHeader)
  326. {
  327.     vGet8FootnotesInfo(pFile, pPPS,
  328.             alBBD, tBBDLen, alSBD, tSBDLen, aucHeader);
  329.     vGet8EndnotesInfo(pFile, pPPS,
  330.             alBBD, tBBDLen, alSBD, tSBDLen, aucHeader);
  331. } /* end of vGet8NotesInfo */
  332.  
  333. /*
  334.  * Build the lists with footnote and endnote information
  335.  */
  336. void
  337. vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
  338.     const long *alBBD, size_t tBBDLen, const long *alSBD, size_t tSBDLen,
  339.     const unsigned char *aucHeader, int iWordVersion)
  340. {
  341.     fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
  342.     fail(iWordVersion < 6 || iWordVersion > 8);
  343.     fail(alBBD == NULL || alSBD == NULL);
  344.  
  345.     switch (iWordVersion) {
  346.     case 6:
  347.     case 7:
  348.         vGet6NotesInfo(pFile, pPPS->tWordDocument.lSb,
  349.             alBBD, tBBDLen, aucHeader);
  350.         break;
  351.     case 8:
  352.         vGet8NotesInfo(pFile, pPPS,
  353.             alBBD, tBBDLen, alSBD, tSBDLen, aucHeader);
  354.         break;
  355.     default:
  356.         werr(0, "Sorry, no notes information");
  357.         break;
  358.     }
  359. } /* end of vGetNotesInfo */
  360.  
  361. /*
  362.  * Get the notetype of the note at the given fileoffset
  363.  */
  364. notetype_enum
  365. eGetNotetype(long lFileOffset)
  366. {
  367.     int    iIndex;
  368.  
  369.     fail(alFootnoteList == NULL && tFootnoteListLength != 0);
  370.     fail(alEndnoteList == NULL && tEndnoteListLength != 0);
  371.  
  372.     /* Go for the easy answer first */
  373.     if (tFootnoteListLength == 0 && tEndnoteListLength == 0) {
  374.         return notetype_is_unknown;
  375.     }
  376.     if (tEndnoteListLength == 0) {
  377.         return notetype_is_footnote;
  378.     }
  379.     if (tFootnoteListLength == 0) {
  380.         return notetype_is_endnote;
  381.     }
  382.     /* No easy answer, so we search */
  383.     for (iIndex = 0; iIndex < (int)tFootnoteListLength; iIndex++) {
  384.         if (alFootnoteList[iIndex] == lFileOffset) {
  385.             return notetype_is_footnote;
  386.         }
  387.     }
  388.     for (iIndex = 0; iIndex < (int)tEndnoteListLength; iIndex++) {
  389.         if (alEndnoteList[iIndex] == lFileOffset) {
  390.             return notetype_is_endnote;
  391.         }
  392.     }
  393.     /* Not found */
  394.     return notetype_is_unknown;
  395. } /* end of eGetNotetype */
  396.