⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datalist.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * datalist.c * Copyright (C) 2000-2002 A.J. van Os; Released under GPL * * Description: * Build, read and destroy a list of Word data blocks */#include <stdlib.h>#include <errno.h>#include "antiword.h"#if defined(__riscos)#define EIO		42#endif /* __riscos *//* * Private structure to hide the way the information * is stored from the rest of the program */typedef struct data_mem_tag {	data_block_type		tInfo;	struct data_mem_tag	*pNext;} data_mem_type;/* Variable to describe the start of the data block list */static data_mem_type	*pAnchor = NULL;/* Variable needed to read the data block list */static data_mem_type	*pBlockLast = NULL;/* Variable needed to read the data block list */static data_mem_type	*pBlockCurrent = NULL;static ULONG	ulBlockOffset = 0;static size_t	tByteNext = 0;/* Last block read */static UCHAR	aucBlock[BIG_BLOCK_SIZE];/* * vDestroyDataBlockList - destroy the data block list */voidvDestroyDataBlockList(void){	data_mem_type	*pCurr, *pNext;	DBG_MSG("vDestroyDataBlockList");	pCurr = pAnchor;	while (pCurr != NULL) {		pNext = pCurr->pNext;		pCurr = xfree(pCurr);		pCurr = pNext;	}	pAnchor = NULL;	/* Reset all the control variables */	pBlockLast = NULL;	pBlockCurrent = NULL;	ulBlockOffset = 0;	tByteNext = 0;} /* end of vDestroyDataBlockList *//* * bAdd2DataBlockList - add an element to the data block list * * Returns TRUE when successful, otherwise FALSE */BOOLbAdd2DataBlockList(const data_block_type *pDataBlock){	data_mem_type	*pListMember;	fail(pDataBlock == NULL);	fail(pDataBlock->ulFileOffset == FC_INVALID);	fail(pDataBlock->ulDataPos == CP_INVALID);	fail(pDataBlock->ulLength == 0);	NO_DBG_MSG("bAdd2DataBlockList");	NO_DBG_HEX(pDataBlock->ulFileOffset);	NO_DBG_HEX(pDataBlock->ulDataPos);	NO_DBG_HEX(pDataBlock->ulLength);	if (pDataBlock->ulFileOffset == FC_INVALID ||	    pDataBlock->ulDataPos == CP_INVALID ||	    pDataBlock->ulLength == 0) {		werr(0, "Software (datablock) error");		return FALSE;	}	/* Check for continuous blocks */	if (pBlockLast != NULL &&	    pBlockLast->tInfo.ulFileOffset +	     pBlockLast->tInfo.ulLength == pDataBlock->ulFileOffset &&	    pBlockLast->tInfo.ulDataPos +	     pBlockLast->tInfo.ulLength == pDataBlock->ulDataPos) {		/* These are continous blocks */		pBlockLast->tInfo.ulLength += pDataBlock->ulLength;		return TRUE;	}	/* Make a new block */	pListMember = xmalloc(sizeof(data_mem_type));	/* Add the block to the data list */	pListMember->tInfo = *pDataBlock;	pListMember->pNext = NULL;	if (pAnchor == NULL) {		pAnchor = pListMember;	} else {		fail(pBlockLast == NULL);		pBlockLast->pNext = pListMember;	}	pBlockLast = pListMember;	return TRUE;} /* end of bAdd2DataBlockList *//* * ulGetDataOffset - get the offset in the data block list * * Get the fileoffset the current position in the data block list */ULONGulGetDataOffset(FILE *pFile){	return pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset + tByteNext;} /* end of ulGetDataOffset *//* * bSetDataOffset - set the offset in the data block list * * Make the given fileoffset the current position in the data block list */BOOLbSetDataOffset(FILE *pFile, ULONG ulFileOffset){	data_mem_type	*pCurr;	size_t	tReadLen;	DBG_HEX(ulFileOffset);	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {		if (ulFileOffset < pCurr->tInfo.ulFileOffset ||		    ulFileOffset >= pCurr->tInfo.ulFileOffset +		     pCurr->tInfo.ulLength) {			/* The file offset is not in this block */			continue;		}		/* Compute the maximum number of bytes to read */		tReadLen = (size_t)(pCurr->tInfo.ulFileOffset +				pCurr->tInfo.ulLength -				ulFileOffset);		/* Compute the real number of bytes to read */		if (tReadLen > sizeof(aucBlock)) {			tReadLen = sizeof(aucBlock);		}		/* Read the bytes */		if (!bReadBytes(aucBlock, tReadLen, ulFileOffset, pFile)) {			return FALSE;		}		/* Set the control variables */		pBlockCurrent = pCurr;		ulBlockOffset = ulFileOffset - pCurr->tInfo.ulFileOffset;		tByteNext = 0;		return TRUE;	}	return FALSE;} /* end of bSetDataOffset *//* * iNextByte - get the next byte from the data block list */intiNextByte(FILE *pFile){	ULONG	ulReadOff;	size_t	tReadLen;	fail(pBlockCurrent == NULL);	if (tByteNext >= sizeof(aucBlock) ||	    ulBlockOffset + tByteNext >= pBlockCurrent->tInfo.ulLength) {		if (ulBlockOffset + sizeof(aucBlock) <					pBlockCurrent->tInfo.ulLength) {			/* Same block, next part */			ulBlockOffset += sizeof(aucBlock);		} else {			/* Next block, first part */			pBlockCurrent = pBlockCurrent->pNext;			ulBlockOffset = 0;		}		if (pBlockCurrent == NULL) {			/* Past the last part of the last block */			errno = EIO;			return EOF;		}		tReadLen = (size_t)				(pBlockCurrent->tInfo.ulLength - ulBlockOffset);		if (tReadLen > sizeof(aucBlock)) {			tReadLen = sizeof(aucBlock);		}		ulReadOff = pBlockCurrent->tInfo.ulFileOffset + ulBlockOffset;		if (!bReadBytes(aucBlock, tReadLen, ulReadOff, pFile)) {			errno = EIO;			return EOF;		}		tByteNext = 0;	}	return (int)aucBlock[tByteNext++];} /* end of iNextByte *//* * usNextWord - get the next word from the data block list * * Read a two byte value in Little Endian order, that means MSB last * * All return values can be valid so errno is set in case of error */USHORTusNextWord(FILE *pFile){	USHORT	usLSB, usMSB;	usLSB = (USHORT)iNextByte(pFile);	if (usLSB == (USHORT)EOF) {		errno = EIO;		return (USHORT)EOF;	}	usMSB = (USHORT)iNextByte(pFile);	if (usMSB == (USHORT)EOF) {		DBG_MSG("usNextWord: Unexpected EOF");		errno = EIO;		return (USHORT)EOF;	}	return (usMSB << 8) | usLSB;} /* end of usNextWord *//* * ulNextLong - get the next long from the data block list * * Read a four byte value in Little Endian order, that means MSW last * * All return values can be valid so errno is set in case of error */ULONGulNextLong(FILE *pFile){	ULONG	ulLSW, ulMSW;	ulLSW = (ULONG)usNextWord(pFile);	if (ulLSW == (ULONG)EOF) {		errno = EIO;		return (ULONG)EOF;	}	ulMSW = (ULONG)usNextWord(pFile);	if (ulMSW == (ULONG)EOF) {		DBG_MSG("ulNextLong: Unexpected EOF");		errno = EIO;		return (ULONG)EOF;	}	return (ulMSW << 16) | ulLSW;} /* end of ulNextLong *//* * usNextWordBE - get the next two byte value * * Read a two byte value in Big Endian order, that means MSB first * * All return values can be valid so errno is set in case of error */USHORTusNextWordBE(FILE *pFile){	USHORT usLSB, usMSB;	usMSB = (USHORT)iNextByte(pFile);	if (usMSB == (USHORT)EOF) {		errno = EIO;		return (USHORT)EOF;	}	usLSB = (USHORT)iNextByte(pFile);	if (usLSB == (USHORT)EOF) {		DBG_MSG("usNextWordBE: Unexpected EOF");		errno = EIO;		return (USHORT)EOF;	}	return (usMSB << 8) | usLSB;} /* end of usNextWordBE *//* * ulNextLongBE - get the next four byte value * * Read a four byte value in Big Endian order, that means MSW first * * All return values can be valid so errno is set in case of error */ULONGulNextLongBE(FILE *pFile){	ULONG	ulLSW, ulMSW;	ulMSW = (ULONG)usNextWordBE(pFile);	if (ulMSW == (ULONG)EOF) {		errno = EIO;		return (ULONG)EOF;	}	ulLSW = (ULONG)usNextWordBE(pFile);	if (ulLSW == (ULONG)EOF) {		DBG_MSG("ulNextLongBE: Unexpected EOF");		errno = EIO;		return (ULONG)EOF;	}	return (ulMSW << 16) | ulLSW;} /* end of ulNextLongBE *//* * tSkipBytes - skip over the given number of bytes * * Returns the number of skipped bytes */size_ttSkipBytes(FILE *pFile, size_t tToSkip){	size_t	tToGo, tMaxMove, tMove;	fail(pFile == NULL);	fail(pBlockCurrent == NULL);	tToGo = tToSkip;	while (tToGo != 0) {		/* Goto the end of the current block */		tMaxMove = min(sizeof(aucBlock) - tByteNext,				(size_t)(pBlockCurrent->tInfo.ulLength -				ulBlockOffset - tByteNext));		tMove = min(tMaxMove, tToGo);		tByteNext += tMove;		tToGo -= tMove;		if (tToGo != 0) {			/* Goto the next block */			if (iNextByte(pFile) == EOF) {				return tToSkip - tToGo;			}			tToGo--;		}	}	return tToSkip;} /* end of tSkipBytes *//* * Translate  a data position to an offset in the file. * Logical to physical offset. * * Returns:	FC_INVALID: in case of error *		otherwise: the computed file offset */ULONGulDataPos2FileOffset(ULONG ulDataPos){	data_mem_type	*pCurr;	fail(ulDataPos == CP_INVALID);	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {		if (ulDataPos < pCurr->tInfo.ulDataPos ||		    ulDataPos >= pCurr->tInfo.ulDataPos +		     pCurr->tInfo.ulLength) {			/* The data offset is not in this block, try the next */			continue;		}		/* The data offset is in the current block */		return pCurr->tInfo.ulFileOffset +				ulDataPos -				pCurr->tInfo.ulDataPos;	}	/* Passed beyond the end of the list */	DBG_HEX_C(ulDataPos != 0, ulDataPos);	return FC_INVALID;} /* end of ulDataPos2FileOffset */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -