📄 listlist.c
字号:
/* * listlist.c * Copyright (C) 2002,2003 A.J. van Os; Released under GPL * * Description: * Build, read and destroy a list of Word list information * * Note: * This list only exists when the Word document is saved by Word 8 or later */#include "antiword.h"/* * Private structure to hide the way the information * is stored from the rest of the program */typedef struct list_desc_tag { list_block_type tInfo; ULONG ulListID; USHORT usIstd; UCHAR ucListLevel; struct list_desc_tag *pNext;} list_desc_type;typedef struct list_value_tag { USHORT usValue; USHORT usListIndex; UCHAR ucListLevel; struct list_value_tag *pNext;} list_value_type;/* Variables needed to describe the LFO list (pllfo) */static ULONG *aulLfoList = NULL;static USHORT usLfoLen = 0;/* Variables needed to write the List Information List */static list_desc_type *pAnchor = NULL;static list_desc_type *pBlockLast = NULL;/* Variable needed for numbering new lists */static list_value_type *pValues = NULL;/* Variables needed for numbering old lists */static int iOldListSeqNumber = 0;static USHORT usOldListValue = 0;/* * vDestroyListInfoList - destroy the List Information List */voidvDestroyListInfoList(void){ list_desc_type *pCurr, *pNext; list_value_type *pValueCurr, *pValueNext; DBG_MSG("vDestroyListInfoList"); /* Free the LFO list */ usLfoLen = 0; aulLfoList = xfree(aulLfoList); /* Free the List Information List */ pCurr = pAnchor; while (pCurr != NULL) { pNext = pCurr->pNext; pCurr = xfree(pCurr); pCurr = pNext; } pAnchor = NULL; /* Reset all control variables */ pBlockLast = NULL; /* Free the values list */ pValueCurr = pValues; while (pValueCurr != NULL) { pValueNext = pValueCurr->pNext; pValueCurr = xfree(pValueCurr); pValueCurr = pValueNext; } pValues = NULL; /* Reset the values for the old lists */ iOldListSeqNumber = 0; usOldListValue = 0;} /* end of vDestroyListInfoList *//* * vBuildLfoList - build the LFO list (pllfo) */voidvBuildLfoList(const UCHAR *aucBuffer, size_t tBufLen){ size_t tRecords; int iIndex; fail(aucBuffer == NULL); if (tBufLen < 4) { return; } tRecords = (size_t)ulGetLong(0, aucBuffer); NO_DBG_DEC(tRecords); if (4 + 16 * tRecords > tBufLen || tRecords >= 0x7fff) { /* Just a sanity check */ DBG_DEC(tRecords); DBG_DEC(4 + 16 * tRecords); DBG_DEC(tBufLen); return; } aulLfoList = xcalloc(tRecords, sizeof(ULONG)); for (iIndex = 0; iIndex < (int)tRecords; iIndex++) { aulLfoList[iIndex] = ulGetLong(4 + 16 * iIndex, aucBuffer); NO_DBG_HEX(aulLfoList[iIndex]); } usLfoLen = (USHORT)tRecords;} /* end of vBuildLfoList *//* * vAdd2ListInfoList - add an element to the List Information list */voidvAdd2ListInfoList(ULONG ulListID, USHORT usIstd, UCHAR ucListLevel, const list_block_type *pListBlock){ list_desc_type *pListMember; fail(pListBlock == NULL); NO_DBG_HEX(ulListID); NO_DBG_DEC(usIstd); NO_DBG_DEC(ucListLevel); NO_DBG_DEC(pListBlock->ulStartAt); NO_DBG_DEC(pListBlock->bNoRestart); NO_DBG_DEC(pListBlock->sLeftIndent); NO_DBG_HEX(pListBlock->ucNFC); NO_DBG_HEX(pListBlock->usListChar); /* Create list member */ pListMember = xmalloc(sizeof(list_desc_type)); /* Fill the list member */ pListMember->tInfo = *pListBlock; pListMember->ulListID = ulListID; pListMember->usIstd = usIstd; pListMember->ucListLevel = ucListLevel; pListMember->pNext = NULL; /* Correct the values where needed */ if (pListMember->tInfo.ulStartAt > 0xffff) { DBG_DEC(pListMember->tInfo.ulStartAt); pListMember->tInfo.ulStartAt = 1; } /* Add the new member to the list */ if (pAnchor == NULL) { pAnchor = pListMember; } else { fail(pBlockLast == NULL); pBlockLast->pNext = pListMember; } pBlockLast = pListMember;} /* end of vAdd2ListInfoList *//* * Get a matching record from the List Information List * * Returns NULL if no matching records is found */const list_block_type *pGetListInfo(USHORT usListIndex, UCHAR ucListLevel){ list_desc_type *pCurr; list_block_type *pNearMatch; ULONG ulListID; if (usListIndex == 0) { return NULL; } if (usListIndex - 1 >= usLfoLen || ucListLevel > 8) { DBG_DEC(usListIndex); DBG_DEC(ucListLevel); return NULL; } fail(aulLfoList == NULL); ulListID = aulLfoList[usListIndex - 1]; NO_DBG_HEX(ulListID); pNearMatch = NULL; for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { if (pCurr->ulListID != ulListID) { /* No match */ continue; } if (pCurr->ucListLevel == ucListLevel) { /* Exact match */ return &pCurr->tInfo; } if (pCurr->ucListLevel == 0) { /* Near match */ pNearMatch = &pCurr->tInfo; } } /* No exact match, use a near match if any */ return pNearMatch;} /* end of pGetListInfo *//* * Get a matching record from the List Information List * * Returns NULL if no matching records is found */const list_block_type *pGetListInfoByIstd(USHORT usIstd){ list_desc_type *pCurr; if (usIstd == ISTD_INVALID || usIstd == STI_NIL || usIstd == STI_USER) { return NULL; } for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { if (pCurr->usIstd == usIstd) { return &pCurr->tInfo; } } return NULL;} /* end of pGetListInfoByIstd *//* * vRestartListValues - reset the less significant list levels */static voidvRestartListValues(USHORT usListIndex, UCHAR ucListLevel){ list_value_type *pPrev, *pCurr, *pNext; int iCounter; iCounter = 0; pPrev = NULL; pCurr = pValues; while (pCurr != NULL) { if (pCurr->usListIndex != usListIndex || pCurr->ucListLevel <= ucListLevel) { pPrev = pCurr; pCurr = pCurr->pNext; continue; } /* Reset the level by deleting the record */ pNext = pCurr->pNext; if (pPrev == NULL) { pValues = pNext; } else { pPrev->pNext = pNext; } DBG_DEC(pCurr->usListIndex); DBG_DEC(pCurr->ucListLevel); pCurr = xfree(pCurr); pCurr = pNext; iCounter++; } DBG_DEC_C(iCounter > 0, iCounter);} /* end of vRestartListValues *//* * usGetListValue - Get the current value of the given list * * Returns the value of the given list */USHORTusGetListValue(int iListSeqNumber, int iWordVersion, const style_block_type *pStyle){ list_value_type *pCurr; USHORT usValue; fail(iListSeqNumber < 0); fail(iListSeqNumber < iOldListSeqNumber); fail(iWordVersion < 0); fail(pStyle == NULL); if (iListSeqNumber <= 0) { return 0; } if (iWordVersion < 8) { /* Old style list */ if (iListSeqNumber == iOldListSeqNumber || (iListSeqNumber == iOldListSeqNumber + 1 && eGetNumType(pStyle->ucNumLevel) == level_type_sequence)) { if (!pStyle->bNumPause) { usOldListValue++; } } else { usOldListValue = pStyle->usStartAt; } iOldListSeqNumber = iListSeqNumber; return usOldListValue; } /* New style list */ if (pStyle->usListIndex == 0 || pStyle->usListIndex - 1 >= usLfoLen || pStyle->ucListLevel > 8) { /* Out of range; no need to search */ return 0; } for (pCurr = pValues; pCurr != NULL; pCurr = pCurr->pNext) { if (pCurr->usListIndex == pStyle->usListIndex && pCurr->ucListLevel == pStyle->ucListLevel) { /* Record found; increment and return the value */ pCurr->usValue++; usValue = pCurr->usValue; if (!pStyle->bNoRestart) { vRestartListValues(pStyle->usListIndex, pStyle->ucListLevel); } return usValue; } } /* Record not found; create it and add it to the front of the list */ pCurr = xmalloc(sizeof(list_value_type)); pCurr->usValue = pStyle->usStartAt; pCurr->usListIndex = pStyle->usListIndex; pCurr->ucListLevel = pStyle->ucListLevel; pCurr->pNext = pValues; pValues = pCurr; usValue = pCurr->usValue; if (!pStyle->bNoRestart) { vRestartListValues(pStyle->usListIndex, pStyle->ucListLevel); } return usValue;} /* end of usGetListValue */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -