?? docdecoder.cpp
字號:
#include "StdAfx.h"
#include ".\docdecoder.h"
CDocDecoder::CDocDecoder(CPublicResource *ps):
CDecoderBase(ps)
{
reset();
}
CDocDecoder::~CDocDecoder(void)
{
}
void
CDocDecoder::vDestroyTextBlockList(void)
{
list_mem_type *apAnchor[5];
list_mem_type *pCurr, *pNext;
int iIndex;
apAnchor[0] = pTextAnchor;
apAnchor[1] = pFootAnchor;
apAnchor[2] = pUnused1Anchor;
apAnchor[3] = pEndAnchor;
apAnchor[4] = pUnused2Anchor;
for (iIndex = 0; iIndex < 5; iIndex++) {
pCurr = apAnchor[iIndex];
while (pCurr != NULL) {
pNext = pCurr->pNext;
pCurr = (list_mem_type *)xfree(pCurr);
pCurr = pNext;
}
}
/* Show that there are no lists any more */
pTextAnchor = NULL;
pFootAnchor = NULL;
pUnused1Anchor = NULL;
pEndAnchor = NULL;
pUnused2Anchor = NULL;
/* Reset all the controle variables */
pBlockLast = NULL;
pTextBlockCurrent = NULL;
pFootBlockCurrent = NULL;
} /* end of vDestroyTextBlockList */
bool
CDocDecoder::bAdd2TextBlockList(text_block_type *pTextBlock)
{
list_mem_type *pListMember;
if (pTextBlock->iFileOffset < 0 ||
pTextBlock->iTextOffset < 0 ||
pTextBlock->iLength <= 0) {
// werr(0, "Software (textblock) error");
return false;
}
/* Check for continuous blocks of the same character size */
if (pBlockLast != NULL &&
pBlockLast->tInfo.iFileOffset +
pBlockLast->tInfo.iLength == pTextBlock->iFileOffset &&
pBlockLast->tInfo.iTextOffset +
pBlockLast->tInfo.iLength == pTextBlock->iTextOffset &&
pBlockLast->tInfo.bUsesUnicode == pTextBlock->bUsesUnicode) {
/* These are continous blocks */
pBlockLast->tInfo.iLength += pTextBlock->iLength;
return TRUE;
}
/* Make a new block */
pListMember = (list_mem_type *)xmalloc(sizeof(list_mem_type));
/* Add the block to the list */
pListMember->tInfo = *pTextBlock;
pListMember->pNext = NULL;
if (pTextAnchor == NULL) {
pTextAnchor = pListMember;
} else {
pBlockLast->pNext = pListMember;
}
pBlockLast = pListMember;
return TRUE;
} /* end of bAdd2TextBlockList */
void
CDocDecoder::vSplitBlockList(int iTextLen, int iFootnoteLen,
int iUnused1Len, int iEndnoteLen, int iUnused2Len,
bool bMustExtend)
{
list_mem_type *apAnchors[5];
list_mem_type *pGarbageAnchor, *pCurr, *pNext;
int iIndex, iCharsToGo, iBytesTooFar;
/* Text block list */
if (iTextLen > 0) {
iCharsToGo = iTextLen;
iBytesTooFar = -1;
for (pCurr = pTextAnchor;
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iCharsToGo -= pCurr->tInfo.iLength / 2;
if (iCharsToGo < 0) {
iBytesTooFar = -2 * iCharsToGo;
}
} else {
iCharsToGo -= pCurr->tInfo.iLength;
if (iCharsToGo < 0) {
iBytesTooFar = -iCharsToGo;
}
}
if (iCharsToGo <= 0) {
break;
}
}
}
/* Split the list */
if (iTextLen <= 0) {
/* Empty text blocks list */
pFootAnchor = pTextAnchor;
pTextAnchor = NULL;
} else if (pCurr == NULL) {
/* No footnote blocks */
pFootAnchor = NULL;
} else if (iCharsToGo == 0) {
/* Move the integral number of footnote blocks */
pFootAnchor = pCurr->pNext;
pCurr->pNext = NULL;
} else {
/* Split the part-text block, part-footnote block */
pFootAnchor = (list_mem_type *)xmalloc(sizeof(list_mem_type));
pFootAnchor->tInfo.iFileOffset =
pCurr->tInfo.iFileOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pFootAnchor->tInfo.iTextOffset =
pCurr->tInfo.iTextOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pFootAnchor->tInfo.iLength = iBytesTooFar;
pCurr->tInfo.iLength -= iBytesTooFar;
pFootAnchor->tInfo.bUsesUnicode = pCurr->tInfo.bUsesUnicode;
/* Move the integral number of footnote blocks */
pFootAnchor->pNext = pCurr->pNext;
pCurr->pNext = NULL;
}
/* Footnote block list */
if (iFootnoteLen > 0) {
iCharsToGo = iFootnoteLen;
iBytesTooFar = -1;
for (pCurr = pFootAnchor;
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iCharsToGo -= pCurr->tInfo.iLength / 2;
if (iCharsToGo < 0) {
iBytesTooFar = -2 * iCharsToGo;
}
} else {
iCharsToGo -= pCurr->tInfo.iLength;
if (iCharsToGo < 0) {
iBytesTooFar = -iCharsToGo;
}
}
if (iCharsToGo <= 0) {
break;
}
}
}
/* Split the list */
if (iFootnoteLen <= 0) {
/* Empty footnote list */
pUnused1Anchor = pFootAnchor;
pFootAnchor = NULL;
} else if (pCurr == NULL) {
/* No unused1 blocks */
pUnused1Anchor = NULL;
} else if (iCharsToGo == 0) {
/* Move the integral number of unused1-list blocks */
pUnused1Anchor = pCurr->pNext;
pCurr->pNext = NULL;
} else {
/* Split the part-footnote block, part-unused1 block */
pUnused1Anchor = (list_mem_type *)xmalloc(sizeof(list_mem_type));
pUnused1Anchor->tInfo.iFileOffset =
pCurr->tInfo.iFileOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pUnused1Anchor->tInfo.iTextOffset =
pCurr->tInfo.iTextOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pUnused1Anchor->tInfo.iLength = iBytesTooFar;
pCurr->tInfo.iLength -= iBytesTooFar;
pUnused1Anchor->tInfo.bUsesUnicode =
pCurr->tInfo.bUsesUnicode;
/* Move the integral number of unused1 blocks */
pUnused1Anchor->pNext = pCurr->pNext;
pCurr->pNext = NULL;
}
/* Unused1 block list */
if (iUnused1Len > 0) {
iCharsToGo = iUnused1Len;
iBytesTooFar = -1;
for (pCurr = pUnused1Anchor;
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iCharsToGo -= pCurr->tInfo.iLength / 2;
if (iCharsToGo < 0) {
iBytesTooFar = -2 * iCharsToGo;
}
} else {
iCharsToGo -= pCurr->tInfo.iLength;
if (iCharsToGo < 0) {
iBytesTooFar = -iCharsToGo;
}
}
if (iCharsToGo <= 0) {
break;
}
}
}
/* Split the list */
if (iUnused1Len <= 0) {
/* Empty unused1 list */
pEndAnchor = pUnused1Anchor;
pUnused1Anchor = NULL;
} else if (pCurr == NULL) {
/* No endnote blocks */
pEndAnchor = NULL;
} else if (iCharsToGo == 0) {
/* Move the intergral number of endnote blocks */
pEndAnchor = pCurr->pNext;
pCurr->pNext = NULL;
} else {
/* Split the part-unused1-list block, part-endnote block */
pEndAnchor = (list_mem_type *)xmalloc(sizeof(list_mem_type));
pEndAnchor->tInfo.iFileOffset =
pCurr->tInfo.iFileOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pEndAnchor->tInfo.iTextOffset =
pCurr->tInfo.iTextOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pEndAnchor->tInfo.iLength = iBytesTooFar;
pCurr->tInfo.iLength -= iBytesTooFar;
pEndAnchor->tInfo.bUsesUnicode = pCurr->tInfo.bUsesUnicode;
/* Move the integral number of endnote blocks */
pEndAnchor->pNext = pCurr->pNext;
pCurr->pNext = NULL;
}
/* Endnote block list */
if (iEndnoteLen > 0) {
iCharsToGo = iEndnoteLen;
iBytesTooFar = -1;
for (pCurr = pEndAnchor;
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iCharsToGo -= pCurr->tInfo.iLength / 2;
if (iCharsToGo <= 0) {
iBytesTooFar = -2 * iCharsToGo;
}
} else {
iCharsToGo -= pCurr->tInfo.iLength;
if (iCharsToGo <= 0) {
iBytesTooFar = -iCharsToGo;
}
}
if (iCharsToGo <= 0) {
break;
}
}
}
/* Split the list */
if (iEndnoteLen <= 0) {
/* Empty endnote list */
pUnused2Anchor = pEndAnchor;
pEndAnchor = NULL;
} else if (pCurr == NULL) {
/* No unused2 blocks */
pUnused2Anchor = NULL;
} else if (iCharsToGo == 0) {
/* Move the intergral number of unused2 blocks */
pUnused2Anchor = pCurr->pNext;
pCurr->pNext = NULL;
} else {
/* Split the part-endnote block, part-unused2 block */
pUnused2Anchor = (list_mem_type *)xmalloc(sizeof(list_mem_type));
pUnused2Anchor->tInfo.iFileOffset =
pCurr->tInfo.iFileOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pUnused2Anchor->tInfo.iTextOffset =
pCurr->tInfo.iTextOffset +
pCurr->tInfo.iLength -
iBytesTooFar;
pUnused2Anchor->tInfo.iLength = iBytesTooFar;
pCurr->tInfo.iLength -= iBytesTooFar;
pUnused2Anchor->tInfo.bUsesUnicode =
pCurr->tInfo.bUsesUnicode;
/* Move the integral number of unused2 blocks */
pUnused2Anchor->pNext = pCurr->pNext;
pCurr->pNext = NULL;
}
/* Unused2 block list */
if (iUnused2Len > 0) {
iCharsToGo = iUnused2Len;
iBytesTooFar = -1;
for (pCurr = pUnused2Anchor;
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iCharsToGo -= pCurr->tInfo.iLength / 2;
if (iCharsToGo < 0) {
iBytesTooFar = -2 * iCharsToGo;
}
} else {
iCharsToGo -= pCurr->tInfo.iLength;
if (iCharsToGo < 0) {
iBytesTooFar = -iCharsToGo;
}
}
if (iCharsToGo <= 0) {
break;
}
}
}
if (iUnused2Len <= 0) {
/* Empty unused2 list */
pGarbageAnchor = pUnused2Anchor;
pUnused2Anchor = NULL;
} else if (pCurr == NULL) {
/* No garbage block list */
pGarbageAnchor = NULL;
} else if (iCharsToGo == 0) {
/* Move the intergral number of garbage blocks */
pGarbageAnchor = pCurr->pNext;
} else {
/* Reduce the part-endnote block */
pCurr->tInfo.iLength -= iBytesTooFar;
/* Move the integral number of garbage blocks */
pGarbageAnchor = pCurr->pNext;
pCurr->pNext = NULL;
}
/* Free the garbage block list, this should never be needed */
pCurr = pGarbageAnchor;
while (pCurr != NULL) {
pNext = pCurr->pNext;
pCurr = (list_mem_type *)xfree(pCurr);
pCurr = pNext;
}
if (!bMustExtend) {
return;
}
/*
* All blocks (except the last one) must have a length that
* is a multiple of the Big Block Size
*/
apAnchors[0] = pTextAnchor;
apAnchors[1] = pFootAnchor;
apAnchors[2] = pUnused1Anchor;
apAnchors[3] = pEndAnchor;
apAnchors[4] = pUnused2Anchor;
for (iIndex = 0; iIndex < 5; iIndex++) {
for (pCurr = apAnchors[iIndex];
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->pNext != NULL &&
pCurr->tInfo.iLength % BIG_BLOCK_SIZE != 0) {
pCurr->tInfo.iLength /= BIG_BLOCK_SIZE;
pCurr->tInfo.iLength++;
pCurr->tInfo.iLength *= BIG_BLOCK_SIZE;
}
}
}
} /* end of vSplitBlockList */
unsigned int
CDocDecoder::uiGetDocumentLength(void)
{
list_mem_type *apAnchors[3];
list_mem_type *pCurr;
int iTotal, iIndex;
apAnchors[0] = pTextAnchor;
apAnchors[1] = pFootAnchor;
apAnchors[2] = pEndAnchor;
iTotal = 0;
for (iIndex = 0; iIndex < 3; iIndex++) {
for (pCurr = apAnchors[iIndex];
pCurr != NULL;
pCurr = pCurr->pNext) {
if (pCurr->tInfo.bUsesUnicode) {
iTotal += pCurr->tInfo.iLength / 2;
} else {
iTotal += pCurr->tInfo.iLength;
}
}
}
return iTotal;
} /* end of uiGetDocumentLength */
int
CDocDecoder::iNextTextByte(unsigned char *pFile, int *piOffset)
{
static int iByteNext = 0;
static int iBlockOffset = 0;
int iReadLen, iReadOff;
if (pTextBlockCurrent == NULL ||
iByteNext >= sizeof(aucBlock) ||
iBlockOffset + iByteNext >= pTextBlockCurrent->tInfo.iLength) {
if (pTextBlockCurrent == NULL) {
/* First block, first part */
pTextBlockCurrent = pTextAnchor;
iBlockOffset = 0;
} else if ((iBlockOffset + (signed)sizeof(aucBlock)) <
pTextBlockCurrent->tInfo.iLength) {
/* Same block, next part */
iBlockOffset += sizeof(aucBlock);
} else {
/* Next block, first part */
pTextBlockCurrent = pTextBlockCurrent->pNext;
iBlockOffset = 0;
}
if (pTextBlockCurrent == NULL) {
/* Past the last part of the last block */
return EOF;
}
iReadLen = pTextBlockCurrent->tInfo.iLength - iBlockOffset;
if (iReadLen > sizeof(aucBlock)) {
iReadLen = sizeof(aucBlock);
}
iReadOff = pTextBlockCurrent->tInfo.iFileOffset +
iBlockOffset;
if (!bReadBytes(aucBlock, iReadLen, iReadOff, pFile)) {
return EOF;
}
iByteNext = 0;
}
if (piOffset != NULL) {
*piOffset = pTextBlockCurrent->tInfo.iFileOffset +
iBlockOffset +
iByteNext;
}
return aucBlock[iByteNext++];
} /* end of iNextTextByte */
int
CDocDecoder::iNextFootByte(unsigned char *pFile, int *piOffset)
{
static int iByteNext = 0;
static int iBlockOffset = 0;
int iReadLen, iReadOff;
if (pFootBlockCurrent == NULL ||
iByteNext >= sizeof(aucBlock) ||
iBlockOffset + iByteNext >= pFootBlockCurrent->tInfo.iLength) {
if (pFootBlockCurrent == NULL) {
/* First block, first part */
pFootBlockCurrent = pFootAnchor;
iBlockOffset = 0;
} else if (iBlockOffset + (signed)sizeof(aucBlock) <
pFootBlockCurrent->tInfo.iLength) {
/* Same block, next part */
iBlockOffset += sizeof(aucBlock);
} else {
/* Next block, first part */
pFootBlockCurrent = pFootBlockCurrent->pNext;
iBlockOffset = 0;
}
if (pFootBlockCurrent == NULL) {
/* Past the last part of the last block */
return EOF;
}
iReadLen = pFootBlockCurrent->tInfo.iLength - iBlockOffset;
if (iReadLen > sizeof(aucBlock)) {
iReadLen = sizeof(aucBlock);
}
iReadOff = pFootBlockCurrent->tInfo.iFileOffset +
iBlockOffset;
if (!bReadBytes(aucBlock, iReadLen, iReadOff, pFile)) {
return EOF;
}
iByteNext = 0;
}
if (piOffset != NULL) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -