00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdlib.h>
00010 #include "antiword.h"
00011
00012
00013
00014
00015
00016
00017 typedef struct list_mem_tag {
00018 text_block_type tInfo;
00019 struct list_mem_tag *pNext;
00020 } list_mem_type;
00021
00022 typedef struct readinfo_tag {
00023 list_mem_type *pBlockCurrent;
00024 ULONG ulBlockOffset;
00025 size_t tByteNext;
00026 UCHAR aucBlock[BIG_BLOCK_SIZE];
00027 } readinfo_type;
00028
00029
00030 static list_mem_type *pTextAnchor = NULL;
00031 static list_mem_type *pFootnoteAnchor = NULL;
00032 static list_mem_type *pHdrFtrAnchor = NULL;
00033 static list_mem_type *pMacroAnchor = NULL;
00034 static list_mem_type *pAnnotationAnchor = NULL;
00035 static list_mem_type *pEndnoteAnchor = NULL;
00036 static list_mem_type *pTextBoxAnchor = NULL;
00037 static list_mem_type *pHdrTextBoxAnchor = NULL;
00038
00039 static list_mem_type *pBlockLast = NULL;
00040
00041 static readinfo_type tOthers = { NULL, 0, 0, };
00042 static readinfo_type tHdrFtr = { NULL, 0, 0, };
00043 static readinfo_type tFootnote = { NULL, 0, 0, };
00044
00045
00046
00047
00048
00049
00050
00051 static list_mem_type *
00052 pFreeOneList(list_mem_type *pAnchor)
00053 {
00054 list_mem_type *pCurr, *pNext;
00055
00056 pCurr = pAnchor;
00057 while (pCurr != NULL) {
00058 pNext = pCurr->pNext;
00059 pCurr = xfree(pCurr);
00060 pCurr = pNext;
00061 }
00062 return NULL;
00063 }
00064
00065
00066
00067
00068 void
00069 vDestroyTextBlockList(void)
00070 {
00071 DBG_MSG("vDestroyTextBlockList");
00072
00073
00074 pTextAnchor = pFreeOneList(pTextAnchor);
00075 pFootnoteAnchor = pFreeOneList(pFootnoteAnchor);
00076 pHdrFtrAnchor = pFreeOneList(pHdrFtrAnchor);
00077 pMacroAnchor = pFreeOneList(pMacroAnchor);
00078 pAnnotationAnchor = pFreeOneList(pAnnotationAnchor);
00079 pEndnoteAnchor = pFreeOneList(pEndnoteAnchor);
00080 pTextBoxAnchor = pFreeOneList(pTextBoxAnchor);
00081 pHdrTextBoxAnchor = pFreeOneList(pHdrTextBoxAnchor);
00082
00083 pBlockLast = NULL;
00084 tOthers.pBlockCurrent = NULL;
00085 tHdrFtr.pBlockCurrent = NULL;
00086 tFootnote.pBlockCurrent = NULL;
00087 }
00088
00089
00090
00091
00092
00093
00094 BOOL
00095 bAdd2TextBlockList(const text_block_type *pTextBlock)
00096 {
00097 list_mem_type *pListMember;
00098
00099 fail(pTextBlock == NULL);
00100 fail(pTextBlock->ulFileOffset == FC_INVALID);
00101 fail(pTextBlock->ulCharPos == CP_INVALID);
00102 fail(pTextBlock->ulLength == 0);
00103 fail(pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength));
00104
00105 NO_DBG_MSG("bAdd2TextBlockList");
00106 NO_DBG_HEX(pTextBlock->ulFileOffset);
00107 NO_DBG_HEX(pTextBlock->ulCharPos);
00108 NO_DBG_HEX(pTextBlock->ulLength);
00109 NO_DBG_DEC(pTextBlock->bUsesUnicode);
00110 NO_DBG_DEC(pTextBlock->usPropMod);
00111
00112 if (pTextBlock->ulFileOffset == FC_INVALID ||
00113 pTextBlock->ulCharPos == CP_INVALID ||
00114 pTextBlock->ulLength == 0 ||
00115 (pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength))) {
00116 werr(0, "Software (textblock) error");
00117 return FALSE;
00118 }
00119
00120
00121
00122
00123 if (pBlockLast != NULL &&
00124 pBlockLast->tInfo.ulFileOffset +
00125 pBlockLast->tInfo.ulLength == pTextBlock->ulFileOffset &&
00126 pBlockLast->tInfo.ulCharPos +
00127 pBlockLast->tInfo.ulLength == pTextBlock->ulCharPos &&
00128 pBlockLast->tInfo.bUsesUnicode == pTextBlock->bUsesUnicode &&
00129 pBlockLast->tInfo.usPropMod == pTextBlock->usPropMod) {
00130
00131 pBlockLast->tInfo.ulLength += pTextBlock->ulLength;
00132 return TRUE;
00133 }
00134
00135 pListMember = xmalloc(sizeof(list_mem_type));
00136
00137 pListMember->tInfo = *pTextBlock;
00138 pListMember->pNext = NULL;
00139 if (pTextAnchor == NULL) {
00140 pTextAnchor = pListMember;
00141 } else {
00142 fail(pBlockLast == NULL);
00143 pBlockLast->pNext = pListMember;
00144 }
00145 pBlockLast = pListMember;
00146 return TRUE;
00147 }
00148
00149
00150
00151
00152 static void
00153 vSpitList(list_mem_type **ppAnchorCurr, list_mem_type **ppAnchorNext,
00154 ULONG ulListLen)
00155 {
00156 list_mem_type *pCurr;
00157 long lCharsToGo, lBytesTooFar;
00158
00159 fail(ppAnchorCurr == NULL);
00160 fail(ppAnchorNext == NULL);
00161 fail(ulListLen > (ULONG)LONG_MAX);
00162
00163 pCurr = NULL;
00164 lCharsToGo = (long)ulListLen;
00165 lBytesTooFar = -1;
00166 if (ulListLen != 0) {
00167 DBG_DEC(ulListLen);
00168 for (pCurr = *ppAnchorCurr;
00169 pCurr != NULL;
00170 pCurr = pCurr->pNext) {
00171 NO_DBG_DEC(pCurr->tInfo.ulLength);
00172 fail(pCurr->tInfo.ulLength == 0);
00173 fail(pCurr->tInfo.ulLength > (ULONG)LONG_MAX);
00174 if (pCurr->tInfo.bUsesUnicode) {
00175 fail(odd(pCurr->tInfo.ulLength));
00176 lCharsToGo -= (long)(pCurr->tInfo.ulLength / 2);
00177 if (lCharsToGo < 0) {
00178 lBytesTooFar = -2 * lCharsToGo;
00179 }
00180 } else {
00181 lCharsToGo -= (long)pCurr->tInfo.ulLength;
00182 if (lCharsToGo < 0) {
00183 lBytesTooFar = -lCharsToGo;
00184 }
00185 }
00186 if (lCharsToGo <= 0) {
00187 break;
00188 }
00189 }
00190 }
00191
00192 if (ulListLen == 0) {
00193
00194 *ppAnchorNext = *ppAnchorCurr;
00195 *ppAnchorCurr = NULL;
00196 } else if (pCurr == NULL) {
00197
00198 *ppAnchorNext = NULL;
00199 } else if (lCharsToGo == 0) {
00200
00201 *ppAnchorNext = pCurr->pNext;
00202 pCurr->pNext = NULL;
00203 } else {
00204
00205 DBG_DEC(lBytesTooFar);
00206 fail(lBytesTooFar <= 0);
00207 *ppAnchorNext = xmalloc(sizeof(list_mem_type));
00208 DBG_HEX(pCurr->tInfo.ulFileOffset);
00209 (*ppAnchorNext)->tInfo.ulFileOffset =
00210 pCurr->tInfo.ulFileOffset +
00211 pCurr->tInfo.ulLength -
00212 lBytesTooFar;
00213 DBG_HEX((*ppAnchorNext)->tInfo.ulFileOffset);
00214 DBG_HEX(pCurr->tInfo.ulCharPos);
00215 (*ppAnchorNext)->tInfo.ulCharPos =
00216 pCurr->tInfo.ulCharPos +
00217 pCurr->tInfo.ulLength -
00218 lBytesTooFar;
00219 DBG_HEX((*ppAnchorNext)->tInfo.ulCharPos);
00220 (*ppAnchorNext)->tInfo.ulLength = (ULONG)lBytesTooFar;
00221 pCurr->tInfo.ulLength -= (ULONG)lBytesTooFar;
00222 (*ppAnchorNext)->tInfo.bUsesUnicode = pCurr->tInfo.bUsesUnicode;
00223 (*ppAnchorNext)->tInfo.usPropMod = pCurr->tInfo.usPropMod;
00224
00225 (*ppAnchorNext)->pNext = pCurr->pNext;
00226 pCurr->pNext = NULL;
00227 }
00228 }
00229
00230 #if defined(DEBUG) || defined(__riscos)
00231
00232
00233
00234
00235
00236 static ULONG
00237 ulComputeListLength(const list_mem_type *pAnchor)
00238 {
00239 const list_mem_type *pCurr;
00240 ULONG ulTotal;
00241
00242 ulTotal = 0;
00243 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
00244 fail(pCurr->tInfo.ulLength == 0);
00245 if (pCurr->tInfo.bUsesUnicode) {
00246 fail(odd(pCurr->tInfo.ulLength));
00247 ulTotal += pCurr->tInfo.ulLength / 2;
00248 } else {
00249 ulTotal += pCurr->tInfo.ulLength;
00250 }
00251 }
00252 return ulTotal;
00253 }
00254 #endif
00255
00256 #if defined(DEBUG)
00257
00258
00259
00260 static void
00261 vCheckList(const list_mem_type *pAnchor, ULONG ulListLen, char *szMsg)
00262 {
00263 ULONG ulTotal;
00264
00265 ulTotal = ulComputeListLength(pAnchor);
00266 DBG_DEC(ulTotal);
00267 if (ulTotal != ulListLen) {
00268 DBG_DEC(ulListLen);
00269 werr(1, szMsg);
00270 }
00271 }
00272 #endif
00273
00274
00275
00276
00277 static BOOL
00278 bIsEmptyBox(FILE *pFile, const list_mem_type *pAnchor)
00279 {
00280 const list_mem_type *pCurr;
00281 size_t tIndex, tSize;
00282 UCHAR *aucBuffer;
00283 char cChar;
00284
00285 fail(pFile == NULL);
00286
00287 if (pAnchor == NULL) {
00288 return TRUE;
00289 }
00290
00291 aucBuffer = NULL;
00292 for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
00293 fail(pCurr->tInfo.ulLength == 0);
00294 tSize = (size_t)pCurr->tInfo.ulLength;
00295 #if defined(__dos) && !defined(__DJGPP__)
00296 if (pCurr->tInfo.ulLength > 0xffffUL) {
00297 tSize = 0xffff;
00298 }
00299 #endif
00300 fail(aucBuffer != NULL);
00301 aucBuffer = xmalloc(tSize);
00302 if (!bReadBytes(aucBuffer, tSize,
00303 pCurr->tInfo.ulFileOffset, pFile)) {
00304 aucBuffer = xfree(aucBuffer);
00305 return FALSE;
00306 }
00307 for (tIndex = 0; tIndex < tSize; tIndex++) {
00308 cChar = (char)aucBuffer[tIndex];
00309 switch (cChar) {
00310 case '\0': case '\r': case '\n':
00311 case '\f': case '\t': case '\v':
00312 case ' ':
00313 break;
00314 default:
00315 aucBuffer = xfree(aucBuffer);
00316 return FALSE;
00317 }
00318 }
00319 aucBuffer = xfree(aucBuffer);
00320 }
00321 fail(aucBuffer != NULL);
00322 return TRUE;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 void
00337 vSplitBlockList(FILE *pFile, ULONG ulTextLen, ULONG ulFootnoteLen,
00338 ULONG ulHdrFtrLen, ULONG ulMacroLen, ULONG ulAnnotationLen,
00339 ULONG ulEndnoteLen, ULONG ulTextBoxLen, ULONG ulHdrTextBoxLen,
00340 BOOL bMustExtend)
00341 {
00342 list_mem_type *apAnchors[8];
00343 list_mem_type *pGarbageAnchor, *pCurr;
00344 size_t tIndex;
00345
00346 DBG_MSG("vSplitBlockList");
00347
00348 pGarbageAnchor = NULL;
00349
00350 DBG_MSG_C(ulTextLen != 0, "Text block list");
00351 vSpitList(&pTextAnchor, &pFootnoteAnchor, ulTextLen);
00352 DBG_MSG_C(ulFootnoteLen != 0, "Footnote block list");
00353 vSpitList(&pFootnoteAnchor, &pHdrFtrAnchor, ulFootnoteLen);
00354 DBG_MSG_C(ulHdrFtrLen != 0, "Header/Footer block list");
00355 vSpitList(&pHdrFtrAnchor, &pMacroAnchor, ulHdrFtrLen);
00356 DBG_MSG_C(ulMacroLen != 0, "Macro block list");
00357 vSpitList(&pMacroAnchor, &pAnnotationAnchor, ulMacroLen);
00358 DBG_MSG_C(ulAnnotationLen != 0, "Annotation block list");
00359 vSpitList(&pAnnotationAnchor, &pEndnoteAnchor, ulAnnotationLen);
00360 DBG_MSG_C(ulEndnoteLen != 0, "Endnote block list");
00361 vSpitList(&pEndnoteAnchor, &pTextBoxAnchor, ulEndnoteLen);
00362 DBG_MSG_C(ulTextBoxLen != 0, "Textbox block list");
00363 vSpitList(&pTextBoxAnchor, &pHdrTextBoxAnchor, ulTextBoxLen);
00364 DBG_MSG_C(ulHdrTextBoxLen != 0, "HeaderTextbox block list");
00365 vSpitList(&pHdrTextBoxAnchor, &pGarbageAnchor, ulHdrTextBoxLen);
00366
00367
00368 DBG_DEC_C(pGarbageAnchor != NULL, pGarbageAnchor->tInfo.ulLength);
00369 pGarbageAnchor = pFreeOneList(pGarbageAnchor);
00370
00371 #if defined(DEBUG)
00372 vCheckList(pTextAnchor, ulTextLen, "Software error (Text)");
00373 vCheckList(pFootnoteAnchor, ulFootnoteLen, "Software error (Footnote)");
00374 vCheckList(pHdrFtrAnchor, ulHdrFtrLen, "Software error (Hdr/Ftr)");
00375 vCheckList(pMacroAnchor, ulMacroLen, "Software error (Macro)");
00376 vCheckList(pAnnotationAnchor, ulAnnotationLen,
00377 "Software error (Annotation)");
00378 vCheckList(pEndnoteAnchor, ulEndnoteLen, "Software error (Endnote)");
00379 vCheckList(pTextBoxAnchor, ulTextBoxLen, "Software error (TextBox)");
00380 vCheckList(pHdrTextBoxAnchor, ulHdrTextBoxLen,
00381 "Software error (HdrTextBox)");
00382 #endif
00383
00384
00385 if (bIsEmptyBox(pFile, pTextBoxAnchor)) {
00386 pTextBoxAnchor = pFreeOneList(pTextBoxAnchor);
00387 }
00388 if (bIsEmptyBox(pFile, pHdrTextBoxAnchor)) {
00389 pHdrTextBoxAnchor = pFreeOneList(pHdrTextBoxAnchor);
00390 }
00391
00392 if (!bMustExtend) {
00393 return;
00394 }
00395
00396
00397
00398
00399
00400 apAnchors[0] = pTextAnchor;
00401 apAnchors[1] = pFootnoteAnchor;
00402 apAnchors[2] = pHdrFtrAnchor;
00403 apAnchors[3] = pMacroAnchor;
00404 apAnchors[4] = pAnnotationAnchor;
00405 apAnchors[5] = pEndnoteAnchor;
00406 apAnchors[6] = pTextBoxAnchor;
00407 apAnchors[7] = pHdrTextBoxAnchor;
00408
00409 for (tIndex = 0; tIndex < elementsof(apAnchors); tIndex++) {
00410 for (pCurr = apAnchors[tIndex];
00411 pCurr != NULL;
00412 pCurr = pCurr->pNext) {
00413 if (pCurr->pNext != NULL &&
00414 pCurr->tInfo.ulLength % BIG_BLOCK_SIZE != 0) {
00415 DBG_DEC(tIndex);
00416 DBG_HEX(pCurr->tInfo.ulFileOffset);
00417 DBG_HEX(pCurr->tInfo.ulCharPos);
00418 DBG_DEC(pCurr->tInfo.ulLength);
00419 pCurr->tInfo.ulLength /= BIG_BLOCK_SIZE;
00420 pCurr->tInfo.ulLength++;
00421 pCurr->tInfo.ulLength *= BIG_BLOCK_SIZE;
00422 DBG_DEC(pCurr->tInfo.ulLength);
00423 }
00424 }
00425 }
00426 }
00427
00428 #if defined(__riscos)
00429
00430
00431
00432
00433
00434 ULONG
00435 ulGetDocumentLength(void)
00436 {
00437 long ulTotal;
00438
00439 DBG_MSG("ulGetDocumentLength");
00440
00441 ulTotal = ulComputeListLength(pTextAnchor);
00442 ulTotal += ulComputeListLength(pFootnoteAnchor);
00443 ulTotal += ulComputeListLength(pEndnoteAnchor);
00444 ulTotal += ulComputeListLength(pTextBoxAnchor);
00445 ulTotal += ulComputeListLength(pHdrTextBoxAnchor);
00446 DBG_DEC(ulTotal);
00447 return ulTotal;
00448 }
00449 #endif
00450
00451 #if 0
00452
00453
00454
00455 BOOL
00456 bExistsHdrFtr(void)
00457 {
00458 return pHdrFtrAnchor != NULL &&
00459 pHdrFtrAnchor->tInfo.ulLength != 0;
00460 }
00461 #endif
00462
00463
00464
00465
00466 BOOL
00467 bExistsTextBox(void)
00468 {
00469 return pTextBoxAnchor != NULL &&
00470 pTextBoxAnchor->tInfo.ulLength != 0;
00471 }
00472
00473
00474
00475
00476 BOOL
00477 bExistsHdrTextBox(void)
00478 {
00479 return pHdrTextBoxAnchor != NULL &&
00480 pHdrTextBoxAnchor->tInfo.ulLength != 0;
00481 }
00482
00483
00484
00485
00486 static USHORT
00487 usGetNextByte(FILE *pFile, readinfo_type *pInfoCurrent, list_mem_type *pAnchor,
00488 ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod)
00489 {
00490 ULONG ulReadOff;
00491 size_t tReadLen;
00492
00493 fail(pInfoCurrent == NULL);
00494
00495 if (pInfoCurrent->pBlockCurrent == NULL ||
00496 pInfoCurrent->tByteNext >= sizeof(pInfoCurrent->aucBlock) ||
00497 pInfoCurrent->ulBlockOffset + pInfoCurrent->tByteNext >=
00498 pInfoCurrent->pBlockCurrent->tInfo.ulLength) {
00499 if (pInfoCurrent->pBlockCurrent == NULL) {
00500
00501 pInfoCurrent->pBlockCurrent = pAnchor;
00502 pInfoCurrent->ulBlockOffset = 0;
00503 } else if (pInfoCurrent->ulBlockOffset +
00504 sizeof(pInfoCurrent->aucBlock) <
00505 pInfoCurrent->pBlockCurrent->tInfo.ulLength) {
00506
00507 pInfoCurrent->ulBlockOffset +=
00508 sizeof(pInfoCurrent->aucBlock);
00509 } else {
00510
00511 pInfoCurrent->pBlockCurrent =
00512 pInfoCurrent->pBlockCurrent->pNext;
00513 pInfoCurrent->ulBlockOffset = 0;
00514 }
00515 if (pInfoCurrent->pBlockCurrent == NULL) {
00516
00517 return (USHORT)EOF;
00518 }
00519 tReadLen = (size_t)
00520 (pInfoCurrent->pBlockCurrent->tInfo.ulLength -
00521 pInfoCurrent->ulBlockOffset);
00522 if (tReadLen > sizeof(pInfoCurrent->aucBlock)) {
00523 tReadLen = sizeof(pInfoCurrent->aucBlock);
00524 }
00525 ulReadOff = pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset +
00526 pInfoCurrent->ulBlockOffset;
00527 if (!bReadBytes(pInfoCurrent->aucBlock,
00528 tReadLen, ulReadOff, pFile)) {
00529
00530 pInfoCurrent->pBlockCurrent = NULL;
00531 return (USHORT)EOF;
00532 }
00533 pInfoCurrent->tByteNext = 0;
00534 }
00535 if (pulFileOffset != NULL) {
00536 *pulFileOffset =
00537 pInfoCurrent->pBlockCurrent->tInfo.ulFileOffset +
00538 pInfoCurrent->ulBlockOffset +
00539 pInfoCurrent->tByteNext;
00540 }
00541 if (pulCharPos != NULL) {
00542 *pulCharPos =
00543 pInfoCurrent->pBlockCurrent->tInfo.ulCharPos +
00544 pInfoCurrent->ulBlockOffset +
00545 pInfoCurrent->tByteNext;
00546 }
00547 if (pusPropMod != NULL) {
00548 *pusPropMod = pInfoCurrent->pBlockCurrent->tInfo.usPropMod;
00549 }
00550 return (USHORT)pInfoCurrent->aucBlock[pInfoCurrent->tByteNext++];
00551 }
00552
00553
00554
00555
00556
00557 static USHORT
00558 usGetNextChar(FILE *pFile, list_id_enum eListID,
00559 ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod)
00560 {
00561 readinfo_type *pReadinfo;
00562 list_mem_type *pAnchor;
00563 USHORT usLSB, usMSB;
00564
00565 switch (eListID) {
00566 case text_list:
00567 pReadinfo = &tOthers;
00568 pAnchor = pTextAnchor;
00569 break;
00570 case footnote_list:
00571 pReadinfo = &tFootnote;
00572 pAnchor = pFootnoteAnchor;
00573 break;
00574 case hdrftr_list:
00575 pReadinfo = &tHdrFtr;
00576 pAnchor = pHdrFtrAnchor;
00577 break;
00578 case endnote_list:
00579 pReadinfo = &tOthers;
00580 pAnchor = pEndnoteAnchor;
00581 break;
00582 case textbox_list:
00583 pReadinfo = &tOthers;
00584 pAnchor = pTextBoxAnchor;
00585 break;
00586 case hdrtextbox_list:
00587 pReadinfo = &tOthers;
00588 pAnchor = pHdrTextBoxAnchor;
00589 break;
00590 default:
00591 DBG_DEC(eListID);
00592 return (USHORT)EOF;
00593 }
00594
00595 usLSB = usGetNextByte(pFile, pReadinfo, pAnchor,
00596 pulFileOffset, pulCharPos, pusPropMod);
00597 if (usLSB == (USHORT)EOF) {
00598 return (USHORT)EOF;
00599 }
00600 fail(pReadinfo->pBlockCurrent == NULL);
00601
00602 if (pReadinfo->pBlockCurrent->tInfo.bUsesUnicode) {
00603 usMSB = usGetNextByte(pFile,
00604 pReadinfo, pAnchor, NULL, NULL, NULL);
00605 } else {
00606 usMSB = 0x00;
00607 }
00608 if (usMSB == (USHORT)EOF) {
00609 DBG_MSG("usGetNextChar: Unexpected EOF");
00610 DBG_HEX_C(pulFileOffset != NULL, *pulFileOffset);
00611 DBG_HEX_C(pulCharPos != NULL, *pulCharPos);
00612 return (USHORT)EOF;
00613 }
00614 return (usMSB << 8) | usLSB;
00615 }
00616
00617
00618
00619
00620 USHORT
00621 usNextChar(FILE *pFile, list_id_enum eListID,
00622 ULONG *pulFileOffset, ULONG *pulCharPos, USHORT *pusPropMod)
00623 {
00624 USHORT usRetVal;
00625
00626 fail(pFile == NULL);
00627
00628 usRetVal = usGetNextChar(pFile, eListID,
00629 pulFileOffset, pulCharPos, pusPropMod);
00630 if (usRetVal == (USHORT)EOF) {
00631 if (pulFileOffset != NULL) {
00632 *pulFileOffset = FC_INVALID;
00633 }
00634 if (pulCharPos != NULL) {
00635 *pulCharPos = CP_INVALID;
00636 }
00637 if (pusPropMod != NULL) {
00638 *pusPropMod = IGNORE_PROPMOD;
00639 }
00640 }
00641 return usRetVal;
00642 }
00643
00644
00645
00646
00647
00648
00649 USHORT
00650 usToHdrFtrPosition(FILE *pFile, ULONG ulCharPos)
00651 {
00652 ULONG ulCharPosCurr;
00653 USHORT usChar;
00654
00655 tHdrFtr.pBlockCurrent = NULL;
00656 do {
00657 usChar = usNextChar(pFile,
00658 hdrftr_list, NULL, &ulCharPosCurr, NULL);
00659 } while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos);
00660 return usChar;
00661 }
00662
00663
00664
00665
00666
00667
00668 USHORT
00669 usToFootnotePosition(FILE *pFile, ULONG ulCharPos)
00670 {
00671 ULONG ulCharPosCurr;
00672 USHORT usChar;
00673
00674 tFootnote.pBlockCurrent = NULL;
00675 do {
00676 usChar = usNextChar(pFile,
00677 footnote_list, NULL, &ulCharPosCurr, NULL);
00678 } while (usChar != (USHORT)EOF && ulCharPosCurr != ulCharPos);
00679 return usChar;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689 ULONG
00690 ulCharPos2FileOffsetX(ULONG ulCharPos, list_id_enum *peListID)
00691 {
00692 static list_id_enum eListIDs[8] = {
00693 text_list, footnote_list, hdrftr_list,
00694 macro_list, annotation_list, endnote_list,
00695 textbox_list, hdrtextbox_list,
00696 };
00697 list_mem_type *apAnchors[8];
00698 list_mem_type *pCurr;
00699 list_id_enum eListGuess;
00700 ULONG ulBestGuess;
00701 size_t tIndex;
00702
00703 fail(peListID == NULL);
00704
00705 if (ulCharPos == CP_INVALID) {
00706 *peListID = no_list;
00707 return FC_INVALID;
00708 }
00709
00710 apAnchors[0] = pTextAnchor;
00711 apAnchors[1] = pFootnoteAnchor;
00712 apAnchors[2] = pHdrFtrAnchor;
00713 apAnchors[3] = pMacroAnchor;
00714 apAnchors[4] = pAnnotationAnchor;
00715 apAnchors[5] = pEndnoteAnchor;
00716 apAnchors[6] = pTextBoxAnchor;
00717 apAnchors[7] = pHdrTextBoxAnchor;
00718
00719 eListGuess = no_list;
00720 ulBestGuess = FC_INVALID;
00721
00722 for (tIndex = 0; tIndex < elementsof(apAnchors); tIndex++) {
00723 for (pCurr = apAnchors[tIndex];
00724 pCurr != NULL;
00725 pCurr = pCurr->pNext) {
00726 if (ulCharPos == pCurr->tInfo.ulCharPos +
00727 pCurr->tInfo.ulLength &&
00728 pCurr->pNext != NULL) {
00729
00730
00731
00732
00733
00734 eListGuess= eListIDs[tIndex];
00735 ulBestGuess = pCurr->pNext->tInfo.ulFileOffset;
00736 }
00737
00738 if (ulCharPos < pCurr->tInfo.ulCharPos ||
00739 ulCharPos >= pCurr->tInfo.ulCharPos +
00740 pCurr->tInfo.ulLength) {
00741
00742 continue;
00743 }
00744
00745
00746 *peListID = eListIDs[tIndex];
00747 return pCurr->tInfo.ulFileOffset +
00748 ulCharPos - pCurr->tInfo.ulCharPos;
00749 }
00750 }
00751
00752 NO_DBG_HEX(ulCharPos);
00753 NO_DBG_HEX(ulBestGuess);
00754 *peListID = eListGuess;
00755 return ulBestGuess;
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765 ULONG
00766 ulCharPos2FileOffset(ULONG ulCharPos)
00767 {
00768 list_id_enum eListID;
00769
00770 return ulCharPos2FileOffsetX(ulCharPos, &eListID);
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 ULONG
00780 ulHdrFtrOffset2CharPos(ULONG ulHdrFtrOffset)
00781 {
00782 list_mem_type *pCurr;
00783 ULONG ulOffset;
00784
00785 ulOffset = ulHdrFtrOffset;
00786 for (pCurr = pHdrFtrAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
00787 if (ulOffset >= pCurr->tInfo.ulLength) {
00788
00789 ulOffset -= pCurr->tInfo.ulLength;
00790 continue;
00791 }
00792 return pCurr->tInfo.ulCharPos + ulOffset;
00793 }
00794 return CP_INVALID;
00795 }
00796
00797
00798
00799
00800
00801
00802 ULONG
00803 ulGetSeqNumber(ULONG ulFileOffset)
00804 {
00805 list_mem_type *pCurr;
00806 ULONG ulSeq;
00807
00808 if (ulFileOffset == FC_INVALID) {
00809 return FC_INVALID;
00810 }
00811
00812 ulSeq = 0;
00813 for (pCurr = pTextAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
00814 if (ulFileOffset >= pCurr->tInfo.ulFileOffset &&
00815 ulFileOffset < pCurr->tInfo.ulFileOffset +
00816 pCurr->tInfo.ulLength) {
00817
00818 return ulSeq + ulFileOffset - pCurr->tInfo.ulFileOffset;
00819 }
00820 ulSeq += pCurr->tInfo.ulLength;
00821 }
00822 return FC_INVALID;
00823 }