datalist.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * datalist.c
  3. * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
  4. *
  5. * Description:
  6. * Build, read and destroy a list of Word data blocks
  7. */
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include "antiword.h"
  11. #if defined(__riscos)
  12. #define EIO 42
  13. #endif /* __riscos */
  14. /*
  15. * Private structure to hide the way the information
  16. * is stored from the rest of the program
  17. */
  18. typedef struct data_mem_tag {
  19. data_block_type tInfo;
  20. struct data_mem_tag *pNext;
  21. } data_mem_type;
  22. /* Variable to describe the start of the data block list */
  23. static data_mem_type *pAnchor = NULL;
  24. /* Variable needed to read the data block list */
  25. static data_mem_type *pBlockLast = NULL;
  26. /* Variable needed to read the data block list */
  27. static data_mem_type *pBlockCurrent = NULL;
  28. static ULONG ulBlockOffset = 0;
  29. static size_t tByteNext = 0;
  30. /* Last block read */
  31. static UCHAR aucBlock[BIG_BLOCK_SIZE];
  32. /*
  33. * vDestroyDataBlockList - destroy the data block list
  34. */
  35. void
  36. vDestroyDataBlockList(void)
  37. {
  38. data_mem_type *pCurr, *pNext;
  39. DBG_MSG("vDestroyDataBlockList");
  40. pCurr = pAnchor;
  41. while (pCurr != NULL) {
  42. pNext = pCurr->pNext;
  43. pCurr = xfree(pCurr);
  44. pCurr = pNext;
  45. }
  46. pAnchor = NULL;
  47. /* Reset all the control variables */
  48. pBlockLast = NULL;
  49. pBlockCurrent = NULL;
  50. ulBlockOffset = 0;
  51. tByteNext = 0;
  52. } /* end of vDestroyDataBlockList */
  53. /*
  54. * bAdd2DataBlockList - add an element to the data block list
  55. *
  56. * Returns TRUE when successful, otherwise FALSE
  57. */
  58. BOOL
  59. bAdd2DataBlockList(const data_block_type *pDataBlock)
  60. {
  61. data_mem_type *pListMember;
  62. fail(pDataBlock == NULL);
  63. fail(pDataBlock->ulFileOffset == FC_INVALID);
  64. fail(pDataBlock->ulDataPos == CP_INVALID);
  65. fail(pDataBlock->ulLength == 0);
  66. NO_DBG_MSG("bAdd2DataBlockList");
  67. NO_DBG_HEX(pDataBlock->ulFileOffset);
  68. NO_DBG_HEX(pDataBlock->ulDataPos);
  69. NO_DBG_HEX(pDataBlock->ulLength);
  70. if (pDataBlock->ulFileOffset == FC_INVALID ||
  71. pDataBlock->ulDataPos == CP_INVALID ||
  72. pDataBlock->ulLength == 0) {
  73. werr(0, "Software (datablock) error");
  74. return FALSE;
  75. }
  76. /* Check for continuous blocks */
  77. if (pBlockLast != NULL &&
  78. pBlockLast->tInfo.ulFileOffset +
  79. pBlockLast->tInfo.ulLength == pDataBlock->ulFileOffset &&
  80. pBlockLast->tInfo.ulDataPos +
  81. pBlockLast->tInfo.ulLength == pDataBlock->ulDataPos) {
  82. /* These are continous blocks */
  83. pBlockLast->tInfo.ulLength += pDataBlock->ulLength;
  84. return TRUE;
  85. }
  86. /* Make a new block */
  87. pListMember = xmalloc(sizeof(data_mem_type));
  88. /* Add the block to the data list */
  89. pListMember->tInfo = *pDataBlock;
  90. pListMember->pNext = NULL;
  91. if (pAnchor == NULL) {
  92. pAnchor = pListMember;
  93. } else {
  94. fail(pBlockLast == NULL);
  95. pBlockLast->pNext = pListMember;
  96. }
  97. pBlockLast = pListMember;
  98. return TRUE;
  99. } /* end of bAdd2DataBlockList */
  100. /*
  101. * ulGetDataOffset - get the offset in the data block list
  102. *
  103. * Get the fileoffset the current position in the data block list
  104. */
  105. ULONG
  106. ulGetDataOffset(FILE *pFile)
  107. {
  108. return pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset + tByteNext;
  109. } /* end of ulGetDataOffset */
  110. /*
  111. * bSetDataOffset - set the offset in the data block list
  112. *
  113. * Make the given fileoffset the current position in the data block list
  114. */
  115. BOOL
  116. bSetDataOffset(FILE *pFile, ULONG ulFileOffset)
  117. {
  118. data_mem_type *pCurr;
  119. size_t tReadLen;
  120. DBG_HEX(ulFileOffset);
  121. for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
  122. if (ulFileOffset < pCurr->tInfo.ulFileOffset ||
  123. ulFileOffset >= pCurr->tInfo.ulFileOffset +
  124. pCurr->tInfo.ulLength) {
  125. /* The file offset is not in this block */
  126. continue;
  127. }
  128. /* Compute the maximum number of bytes to read */
  129. tReadLen = (size_t)(pCurr->tInfo.ulFileOffset +
  130. pCurr->tInfo.ulLength -
  131. ulFileOffset);
  132. /* Compute the real number of bytes to read */
  133. if (tReadLen > sizeof(aucBlock)) {
  134. tReadLen = sizeof(aucBlock);
  135. }
  136. /* Read the bytes */
  137. if (!bReadBytes(aucBlock, tReadLen, ulFileOffset, pFile)) {
  138. return FALSE;
  139. }
  140. /* Set the control variables */
  141. pBlockCurrent = pCurr;
  142. ulBlockOffset = ulFileOffset - pCurr->tInfo.ulFileOffset;
  143. tByteNext = 0;
  144. return TRUE;
  145. }
  146. return FALSE;
  147. } /* end of bSetDataOffset */
  148. /*
  149. * iNextByte - get the next byte from the data block list
  150. */
  151. int
  152. iNextByte(FILE *pFile)
  153. {
  154. ULONG ulReadOff;
  155. size_t tReadLen;
  156. fail(pBlockCurrent == NULL);
  157. if (tByteNext >= sizeof(aucBlock) ||
  158. ulBlockOffset + tByteNext >= pBlockCurrent->tInfo.ulLength) {
  159. if (ulBlockOffset + sizeof(aucBlock) <
  160. pBlockCurrent->tInfo.ulLength) {
  161. /* Same block, next part */
  162. ulBlockOffset += sizeof(aucBlock);
  163. } else {
  164. /* Next block, first part */
  165. pBlockCurrent = pBlockCurrent->pNext;
  166. ulBlockOffset = 0;
  167. }
  168. if (pBlockCurrent == NULL) {
  169. /* Past the last part of the last block */
  170. errno = EIO;
  171. return EOF;
  172. }
  173. tReadLen = (size_t)
  174. (pBlockCurrent->tInfo.ulLength - ulBlockOffset);
  175. if (tReadLen > sizeof(aucBlock)) {
  176. tReadLen = sizeof(aucBlock);
  177. }
  178. ulReadOff = pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset;
  179. if (!bReadBytes(aucBlock, tReadLen, ulReadOff, pFile)) {
  180. errno = EIO;
  181. return EOF;
  182. }
  183. tByteNext = 0;
  184. }
  185. return (int)aucBlock[tByteNext++];
  186. } /* end of iNextByte */
  187. /*
  188. * usNextWord - get the next word from the data block list
  189. *
  190. * Read a two byte value in Little Endian order, that means MSB last
  191. *
  192. * All return values can be valid so errno is set in case of error
  193. */
  194. USHORT
  195. usNextWord(FILE *pFile)
  196. {
  197. USHORT usLSB, usMSB;
  198. usLSB = (USHORT)iNextByte(pFile);
  199. if (usLSB == (USHORT)EOF) {
  200. errno = EIO;
  201. return (USHORT)EOF;
  202. }
  203. usMSB = (USHORT)iNextByte(pFile);
  204. if (usMSB == (USHORT)EOF) {
  205. DBG_MSG("usNextWord: Unexpected EOF");
  206. errno = EIO;
  207. return (USHORT)EOF;
  208. }
  209. return (usMSB << 8) | usLSB;
  210. } /* end of usNextWord */
  211. /*
  212. * ulNextLong - get the next long from the data block list
  213. *
  214. * Read a four byte value in Little Endian order, that means MSW last
  215. *
  216. * All return values can be valid so errno is set in case of error
  217. */
  218. ULONG
  219. ulNextLong(FILE *pFile)
  220. {
  221. ULONG ulLSW, ulMSW;
  222. ulLSW = (ULONG)usNextWord(pFile);
  223. if (ulLSW == (ULONG)EOF) {
  224. errno = EIO;
  225. return (ULONG)EOF;
  226. }
  227. ulMSW = (ULONG)usNextWord(pFile);
  228. if (ulMSW == (ULONG)EOF) {
  229. DBG_MSG("ulNextLong: Unexpected EOF");
  230. errno = EIO;
  231. return (ULONG)EOF;
  232. }
  233. return (ulMSW << 16) | ulLSW;
  234. } /* end of ulNextLong */
  235. /*
  236. * usNextWordBE - get the next two byte value
  237. *
  238. * Read a two byte value in Big Endian order, that means MSB first
  239. *
  240. * All return values can be valid so errno is set in case of error
  241. */
  242. USHORT
  243. usNextWordBE(FILE *pFile)
  244. {
  245. USHORT usLSB, usMSB;
  246. usMSB = (USHORT)iNextByte(pFile);
  247. if (usMSB == (USHORT)EOF) {
  248. errno = EIO;
  249. return (USHORT)EOF;
  250. }
  251. usLSB = (USHORT)iNextByte(pFile);
  252. if (usLSB == (USHORT)EOF) {
  253. DBG_MSG("usNextWordBE: Unexpected EOF");
  254. errno = EIO;
  255. return (USHORT)EOF;
  256. }
  257. return (usMSB << 8) | usLSB;
  258. } /* end of usNextWordBE */
  259. /*
  260. * ulNextLongBE - get the next four byte value
  261. *
  262. * Read a four byte value in Big Endian order, that means MSW first
  263. *
  264. * All return values can be valid so errno is set in case of error
  265. */
  266. ULONG
  267. ulNextLongBE(FILE *pFile)
  268. {
  269. ULONG ulLSW, ulMSW;
  270. ulMSW = (ULONG)usNextWordBE(pFile);
  271. if (ulMSW == (ULONG)EOF) {
  272. errno = EIO;
  273. return (ULONG)EOF;
  274. }
  275. ulLSW = (ULONG)usNextWordBE(pFile);
  276. if (ulLSW == (ULONG)EOF) {
  277. DBG_MSG("ulNextLongBE: Unexpected EOF");
  278. errno = EIO;
  279. return (ULONG)EOF;
  280. }
  281. return (ulMSW << 16) | ulLSW;
  282. } /* end of ulNextLongBE */
  283. /*
  284. * tSkipBytes - skip over the given number of bytes
  285. *
  286. * Returns the number of skipped bytes
  287. */
  288. size_t
  289. tSkipBytes(FILE *pFile, size_t tToSkip)
  290. {
  291. size_t tToGo, tMaxMove, tMove;
  292. fail(pFile == NULL);
  293. fail(pBlockCurrent == NULL);
  294. tToGo = tToSkip;
  295. while (tToGo != 0) {
  296. /* Goto the end of the current block */
  297. tMaxMove = min(sizeof(aucBlock) - tByteNext,
  298. (size_t)(pBlockCurrent->tInfo.ulLength -
  299. ulBlockOffset - tByteNext));
  300. tMove = min(tMaxMove, tToGo);
  301. tByteNext += tMove;
  302. tToGo -= tMove;
  303. if (tToGo != 0) {
  304. /* Goto the next block */
  305. if (iNextByte(pFile) == EOF) {
  306. return tToSkip - tToGo;
  307. }
  308. tToGo--;
  309. }
  310. }
  311. return tToSkip;
  312. } /* end of tSkipBytes */
  313. /*
  314. * Translate a data position to an offset in the file.
  315. * Logical to physical offset.
  316. *
  317. * Returns: FC_INVALID: in case of error
  318. * otherwise: the computed file offset
  319. */
  320. ULONG
  321. ulDataPos2FileOffset(ULONG ulDataPos)
  322. {
  323. data_mem_type *pCurr;
  324. fail(ulDataPos == CP_INVALID);
  325. for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
  326. if (ulDataPos < pCurr->tInfo.ulDataPos ||
  327. ulDataPos >= pCurr->tInfo.ulDataPos +
  328. pCurr->tInfo.ulLength) {
  329. /* The data offset is not in this block, try the next */
  330. continue;
  331. }
  332. /* The data offset is in the current block */
  333. return pCurr->tInfo.ulFileOffset +
  334. ulDataPos -
  335. pCurr->tInfo.ulDataPos;
  336. }
  337. /* Passed beyond the end of the list */
  338. DBG_HEX_C(ulDataPos != 0, ulDataPos);
  339. return FC_INVALID;
  340. } /* end of ulDataPos2FileOffset */