1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <resourcemodel/exceptions.hxx>
25 #include <resourcemodel/QNameToString.hxx>
26 #include <WW8DocumentImpl.hxx>
27 #include <WW8FKPImpl.hxx>
28 #include <WW8PieceTableImpl.hxx>
29 #include <WW8BinTableImpl.hxx>
30 #include <WW8StreamImpl.hxx>
31 #include <WW8Sttbf.hxx>
32 #include <Dff.hxx>
33 #include <iterator>
34 #include <XNoteHelperImpl.hxx>
35 #include <rtl/ustring.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <doctokLoggers.hxx>
38 
39 namespace writerfilter {
40 namespace doctok
41 {
42 
43 using namespace ::std;
44 
45 template <class T>
46 struct PLCFHelper
47 {
processPLCFCpAndFcswriterfilter::doctok::PLCFHelper48     static void processPLCFCpAndFcs(WW8DocumentImpl & rDoc,
49                                     WW8PieceTable::Pointer_t pPieceTable,
50                                     typename PLCF<T>::Pointer_t pPLCF,
51                                     PropertyType eType,
52                                     sal_uInt32 nOffset)
53     {
54         sal_uInt32 nCount = pPLCF->getEntryCount();
55         for (sal_uInt32 n = 0; n < nCount; ++n)
56         {
57             Cp aCp(pPLCF->getFc(n) + nOffset);
58             CpAndFc aCpAndFc = pPieceTable->createCpAndFc(aCp, eType);
59 
60             rDoc.insertCpAndFc(aCpAndFc);
61         }
62     }
63 };
64 
65 // WW8DocumentIteratorImpl
operator ==(const WW8DocumentIterator & rA,const WW8DocumentIterator & rB)66 bool operator == (const WW8DocumentIterator & rA,
67                   const WW8DocumentIterator & rB)
68 {
69     return rA.equal(rB);
70 }
71 
~WW8DocumentIterator()72 WW8DocumentIterator::~WW8DocumentIterator()
73 {
74 }
75 
~WW8DocumentIteratorImpl()76 WW8DocumentIteratorImpl::~WW8DocumentIteratorImpl()
77 {
78 }
79 
operator ++()80 WW8DocumentIterator & WW8DocumentIteratorImpl::operator++()
81 {
82     mCpAndFc = mpDocument->getNextCp(mCpAndFc);
83 
84     return *this;
85 }
86 
operator --()87 WW8DocumentIterator & WW8DocumentIteratorImpl::operator--()
88 {
89     mCpAndFc = mpDocument->getPrevCp(mCpAndFc);
90 
91     return *this;
92 }
93 
equal(const WW8DocumentIterator & rIt_) const94 bool WW8DocumentIteratorImpl::equal(const WW8DocumentIterator & rIt_) const
95 {
96     const WW8DocumentIteratorImpl & rIt =
97         dynamic_cast<const WW8DocumentIteratorImpl &>(rIt_);
98 
99     return mCpAndFc == rIt.mCpAndFc && mpDocument == rIt.mpDocument;
100 }
101 
102 writerfilter::Reference<Properties>::Pointer_t
getProperties() const103 WW8DocumentIteratorImpl::getProperties() const
104 {
105     return mpDocument->getProperties(mCpAndFc);
106 }
107 
108 writerfilter::Reference<Stream>::Pointer_t
getSubDocument() const109 WW8DocumentIteratorImpl::getSubDocument() const
110 {
111     return mpDocument->getSubDocument(mCpAndFc);
112 }
113 
getSED() const114 WW8SED * WW8DocumentIteratorImpl::getSED() const
115 {
116     return mpDocument->getSED(mCpAndFc);
117 }
118 
getText()119 WW8Stream::Sequence WW8DocumentIteratorImpl::getText()
120 {
121     return mpDocument->getText(mCpAndFc);
122 }
123 
124 writerfilter::Reference<Properties>::Pointer_t
getShape() const125 WW8DocumentIteratorImpl::getShape() const
126 {
127     return mpDocument->getShape(mCpAndFc);
128 }
129 
getPropertyType() const130 PropertyType WW8DocumentIteratorImpl::getPropertyType() const
131 {
132     return mCpAndFc.getType();
133 }
134 
isComplex() const135 bool WW8DocumentIteratorImpl::isComplex() const
136 {
137     return mCpAndFc.isComplex();
138 }
139 
dump(ostream & o) const140 void WW8DocumentIteratorImpl::dump(ostream & o) const
141 {
142     o << mCpAndFc;
143 }
144 
toString() const145 string WW8DocumentIteratorImpl::toString() const
146 {
147     return mCpAndFc.toString();
148 }
149 
150 // WW8DocumentImpl
151 
~WW8Document()152 WW8Document::~WW8Document()
153 {
154 }
155 
156 #ifdef DEBUG
157 class WW8IdToString : public IdToString
158 {
159 public:
WW8IdToString()160     WW8IdToString() : IdToString() {}
~WW8IdToString()161     virtual ~WW8IdToString() {}
162 
toString(const Id & rId) const163     virtual string toString(const Id & rId) const
164     {
165         string s((*SprmIdToString::Instance())(rId));
166 
167         if (s.size() == 0)
168             s = (*QNameToString::Instance())(rId);
169 
170         return s;
171     }
172 };
173 #endif
174 
~WW8DocumentImpl()175 WW8DocumentImpl::~WW8DocumentImpl()
176 {
177 }
178 
WW8DocumentImpl(WW8Stream::Pointer_t rpStream)179 WW8DocumentImpl::WW8DocumentImpl(WW8Stream::Pointer_t rpStream)
180 : bSubDocument(false), mfcPicLoc(0), mbPicIsData(false), mpStream(rpStream),
181 mbInSection(false), mbInParagraphGroup(false), mbInCharacterGroup(false)
182 {
183     mpDocStream = getSubStream(::rtl::OUString::createFromAscii
184                                ("WordDocument"));
185 
186     mpSummaryInformationStream = getSubStream(::rtl::OUString::createFromAscii
187                                               ("\5SummaryInformation"));
188 
189     try
190     {
191         mpDataStream = getSubStream(::rtl::OUString::createFromAscii
192                                     ("Data"));
193     }
194     catch (ExceptionNotFound e)
195     {
196     }
197 
198     try
199     {
200         mpCompObjStream = getSubStream(::rtl::OUString::createFromAscii
201                                        ("\1CompObj"));
202     }
203     catch (ExceptionNotFound e)
204     {
205     }
206 
207     mpCHPFKPCache =
208         WW8FKPCache::Pointer_t(new WW8CHPFKPCacheImpl(mpDocStream, 5));
209     mpPAPFKPCache =
210         WW8FKPCache::Pointer_t(new WW8PAPFKPCacheImpl(mpDocStream, 5));
211 
212     mpFib = WW8Fib::Pointer_t(new WW8Fib(*mpDocStream));
213 
214     switch (mpFib->get_fWhichTblStm())
215     {
216     case 0:
217         mpTableStream = getSubStream(::rtl::OUString::createFromAscii
218                                      ("0Table"));
219 
220         break;
221 
222     case 1:
223         mpTableStream = getSubStream(::rtl::OUString::createFromAscii
224                                      ("1Table"));
225 
226         break;
227 
228     default:
229         break;
230     }
231 
232     if (mpFib->get_nFib() >= 0xD9)
233     {
234         mpFibRgFcLcb2000.reset(new WW8FibRgFcLcb2000(*mpFib));
235     }
236 
237     if (mpTableStream.get() == NULL)
238         throw ExceptionNotFound("Table stream not found.");
239 
240     mpPieceTable =
241         WW8PieceTable::Pointer_t
242         (new WW8PieceTableImpl(*mpTableStream, mpFib->get_fcClx(),
243                                mpFib->get_lcbClx()));
244 
245     {
246         Cp aCp(mpPieceTable->getLastCp());
247         Fc aFc(mpPieceTable->getLastFc());
248         CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
249         mCpAndFcs.insert(aCpAndFc);
250     }
251 
252     {
253         Cp aCp(mpFib->get_ccpText());
254 
255         mDocumentEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
256                                       PROP_DOC);
257         mCpAndFcs.insert(mDocumentEndCpAndFc);
258 
259         aCp += mpFib->get_ccpFtn();
260         mFootnoteEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
261                                       PROP_DOC);
262         mCpAndFcs.insert(mFootnoteEndCpAndFc);
263 
264         aCp += mpFib->get_ccpHdd();
265         mHeaderEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
266                                     PROP_DOC);
267         mCpAndFcs.insert(mHeaderEndCpAndFc);
268 
269         aCp += mpFib->get_ccpAtn();
270         mAnnotationEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
271                                         PROP_DOC);
272         mCpAndFcs.insert(mAnnotationEndCpAndFc);
273 
274         aCp += mpFib->get_ccpEdn();
275         mEndnoteEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
276                                      PROP_DOC);
277         mCpAndFcs.insert(mEndnoteEndCpAndFc);
278 
279         aCp += mpFib->get_ccpTxbx();
280         mTextboxEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
281                                      PROP_DOC);
282         mCpAndFcs.insert(mTextboxEndCpAndFc);
283 
284         aCp += mpFib->get_ccpHdrTxbx();
285         mTextboxHeaderEndCpAndFc = CpAndFc(aCp, mpPieceTable->cp2fc(aCp),
286                                            PROP_DOC);
287         mCpAndFcs.insert(mTextboxHeaderEndCpAndFc);
288     }
289 
290     mpBinTablePAPX =
291         WW8BinTable::Pointer_t(new WW8BinTableImpl
292                                (*mpTableStream,
293                                 mpFib->get_fcPlcfbtePapx(),
294                                 mpFib->get_lcbPlcfbtePapx()));
295 
296     //clog << "BinTable(PAP):" << mpBinTablePAPX->toString();
297 
298     parseBinTableCpAndFcs(*mpBinTablePAPX, PROP_PAP);
299 
300     mpBinTableCHPX =
301         WW8BinTable::Pointer_t(new WW8BinTableImpl
302                                (*mpTableStream,
303                                 mpFib->get_fcPlcfbteChpx(),
304                                 mpFib->get_lcbPlcfbteChpx()));
305 
306     //clog << "BinTable(CHP):" << mpBinTableCHPX->toString();
307 
308     parseBinTableCpAndFcs(*mpBinTableCHPX, PROP_CHP);
309 
310     mpSEDs = PLCF<WW8SED>::Pointer_t(new PLCF<WW8SED>
311                                      (*mpTableStream,
312                                       mpFib->get_fcPlcfsed(),
313                                       mpFib->get_lcbPlcfsed()));
314 
315     //mpSEDs->dump(clog);
316 
317     {
318         PLCFHelper<WW8SED>::processPLCFCpAndFcs
319             (*this, mpPieceTable, mpSEDs, PROP_SEC, 0);
320     }
321 
322     sal_uInt32 nHeaders = getHeaderCount();
323 
324     if (nHeaders > 0)
325     {
326         mpHeaderOffsets = WW8StructBase::Pointer_t
327             (new WW8StructBase(*mpTableStream,
328                                mpFib->get_fcPlcfhdd(),
329                                mpFib->get_lcbPlcfhdd()));
330 
331         {
332             for (sal_uInt32 n = 0; n <= nHeaders; ++n)
333             {
334                 CpAndFc aCpAndFc(getHeaderCpAndFc(n));
335 
336                 mCpAndFcs.insert(aCpAndFc);
337             }
338         }
339     }
340 
341     if (mpFib->get_lcbPlcffndTxt() > 0)
342     {
343         WW8StructBase::Pointer_t pCps
344             (new WW8StructBase(*mpTableStream,
345                                mpFib->get_fcPlcffndTxt(),
346                                mpFib->get_lcbPlcffndTxt()));
347 
348         PLCF<WW8FRD>::Pointer_t pRefs
349             (new PLCF<WW8FRD>(*mpTableStream,
350                                mpFib->get_fcPlcffndRef(),
351                                mpFib->get_lcbPlcffndRef()));
352 
353         mpFootnoteHelper = XNoteHelper<WW8FRD>::Pointer_t
354             (new XNoteHelper<WW8FRD>(pCps, pRefs, mpPieceTable, this,
355                              PROP_FOOTNOTE, getDocumentEndCp()));
356 
357         mpFootnoteHelper->init();
358     }
359 
360     if (mpFib->get_lcbPlcfendTxt() > 0)
361     {
362         WW8StructBase::Pointer_t pCps
363             (new WW8StructBase(*mpTableStream,
364                                mpFib->get_fcPlcfendTxt(),
365                                mpFib->get_lcbPlcfendTxt()));
366 
367         PLCF<WW8FRD>::Pointer_t pRefs
368             (new PLCF<WW8FRD>(*mpTableStream,
369                                mpFib->get_fcPlcfendRef(),
370                                mpFib->get_lcbPlcfendRef()));
371 
372         mpEndnoteHelper = XNoteHelper<WW8FRD>::Pointer_t
373             (new XNoteHelper<WW8FRD>(pCps, pRefs, mpPieceTable, this,
374                              PROP_ENDNOTE, getAnnotationEndCp()));
375 
376         mpEndnoteHelper->init();
377     }
378 
379     if (mpFib->get_lcbPlcfandTxt() > 0)
380     {
381         WW8StructBase::Pointer_t pCps
382             (new WW8StructBase(*mpTableStream,
383                                mpFib->get_fcPlcfandTxt(),
384                                mpFib->get_lcbPlcfandTxt()));
385 
386         PLCF<WW8ATRD>::Pointer_t pRefs
387             (new PLCF<WW8ATRD>(*mpTableStream,
388                                mpFib->get_fcPlcfandRef(),
389                                mpFib->get_lcbPlcfandRef()));
390 
391         mpAnnotationHelper = XNoteHelper<WW8ATRD>::Pointer_t
392             (new XNoteHelper<WW8ATRD>(pCps, pRefs, mpPieceTable, this,
393                                    PROP_ANNOTATION, getHeaderEndCp()));
394 
395         mpAnnotationHelper->init();
396     }
397 
398     if (mpFib->get_lcbSttbfbkmk() > 0)
399     {
400         PLCF<WW8BKF>::Pointer_t pStartCps
401             (new PLCF<WW8BKF>(*mpTableStream, mpFib->get_fcPlcfbkf(),
402                               mpFib->get_lcbPlcfbkf()));
403 
404         WW8StructBase::Pointer_t pEndCps
405             (new WW8StructBase(*mpTableStream, mpFib->get_fcPlcfbkl(),
406                                mpFib->get_lcbPlcfbkl()));
407 
408         WW8Sttbf::Pointer_t pNames
409             (new WW8Sttbf(*mpTableStream, mpFib->get_fcSttbfbkmk(),
410                           mpFib->get_lcbSttbfbkmk()));
411 
412         mpBookmarkHelper = BookmarkHelper::Pointer_t
413             (new BookmarkHelper(pStartCps, pEndCps, pNames, mpPieceTable, this));
414 
415         mpBookmarkHelper->init();
416     }
417 
418     {
419         PLCF<WW8FLD>::Pointer_t pPlcffldMom;
420 
421         if (mpFib->get_lcbPlcffldMom() > 0)
422         {
423             pPlcffldMom = PLCF<WW8FLD>::Pointer_t
424                 (new PLCF<WW8FLD>(*mpTableStream,
425                                   mpFib->get_fcPlcffldMom(),
426                                   mpFib->get_lcbPlcffldMom()));
427 
428             mpFieldHelper = FieldHelper::Pointer_t
429                 (new FieldHelper(pPlcffldMom,
430                                  this));
431 
432             mpFieldHelper->init();
433         }
434     }
435 
436     PLCF<WW8FSPA>::Pointer_t pPlcspaMom;
437     if (mpFib->get_lcbPlcspaMom() > 0)
438     {
439         pPlcspaMom = PLCF<WW8FSPA>::Pointer_t
440             (new PLCF<WW8FSPA>
441              (*mpTableStream, mpFib->get_fcPlcspaMom(),
442               mpFib->get_lcbPlcspaMom()));
443     }
444 
445     PLCF<WW8FSPA>::Pointer_t pPlcspaHdr;
446     if (mpFib->get_lcbPlcspaHdr() > 0)
447     {
448         pPlcspaHdr = PLCF<WW8FSPA>::Pointer_t
449             (new PLCF<WW8FSPA>
450              (*mpTableStream, mpFib->get_fcPlcspaHdr(),
451               mpFib->get_lcbPlcspaHdr()));
452     }
453 
454     mpShapeHelper = ShapeHelper::Pointer_t
455         (new ShapeHelper(pPlcspaMom, pPlcspaHdr, this));
456 
457     mpShapeHelper->init();
458 
459     PLCF<WW8BKD>::Pointer_t pPlcbkdMother;
460     if (mpFib->get_fcBkdMother() > 0 && mpFib->get_lcbBkdMother() > 0)
461     {
462         pPlcbkdMother = PLCF<WW8BKD>::Pointer_t
463             (new PLCF<WW8BKD>
464              (*mpTableStream, mpFib->get_fcBkdMother(),
465               mpFib->get_lcbBkdMother()));
466     }
467 
468     mpBreakHelper = BreakHelper::Pointer_t
469         (new BreakHelper(pPlcbkdMother, this));
470 
471     mpBreakHelper->init();
472 
473     if (mpFib->get_fcDggInfo() != 0 && mpFib->get_lcbDggInfo() > 0)
474     {
475         mpDffBlock = DffBlock::Pointer_t
476             (new DffBlock(*mpTableStream, mpFib->get_fcDggInfo(),
477                          mpFib->get_lcbDggInfo(), 1));
478 
479         mpDffBlock->setDocument(this);
480     }
481 
482     if (mpFib->get_lcbPlcftxbxTxt() > 0)
483     {
484         mpTextBoxStories = PLCF<WW8FTXBXS>::Pointer_t
485             (new PLCF<WW8FTXBXS>(*mpTableStream,
486                                  mpFib->get_fcPlcftxbxTxt(),
487                                  mpFib->get_lcbPlcftxbxTxt()));
488 
489         PLCFHelper<WW8FTXBXS>::processPLCFCpAndFcs
490             (*this, mpPieceTable, mpTextBoxStories, PROP_DOC,
491              mEndnoteEndCpAndFc.getCp().get());
492     }
493 
494     if (mCpAndFcs.size() > 0)
495     {
496         mCpAndFcStart = *mCpAndFcs.begin();
497         mCpAndFcEnd = getDocumentEndCp();
498     }
499 }
500 
isSpecial(sal_uInt32 nChar)501 bool WW8DocumentImpl::isSpecial(sal_uInt32 nChar)
502 {
503     bool bResult = false;
504 
505     if (nChar <= 8)
506         bResult = true;
507     else if (nChar >= 10)
508     {
509         if (nChar == 12)
510             bResult= true;
511         else if (nChar <= 16)
512             bResult = true;
513         else if (nChar >= 22)
514         {
515             if (nChar <= 30)
516                 bResult = true;
517             else if (nChar >= 33)
518             {
519                 if (nChar <= 39)
520                     bResult = true;
521                 else if (nChar == 41)
522                     bResult = true;
523             }
524         }
525     }
526 
527     return bResult;
528 }
529 
WW8DocumentImpl(const WW8DocumentImpl & rSrc,const CpAndFc & rStart,const CpAndFc & rEnd)530 WW8DocumentImpl::WW8DocumentImpl(const WW8DocumentImpl & rSrc,
531                                  const CpAndFc & rStart, const CpAndFc & rEnd)
532 : bSubDocument(true), mfcPicLoc(0), mbPicIsData(false)
533 {
534     Assign(rSrc);
535 
536     mCpAndFcStart = rStart;
537     mCpAndFcEnd = rEnd;
538 }
539 
Assign(const WW8DocumentImpl & rSrc)540 WW8DocumentImpl & WW8DocumentImpl::Assign(const WW8DocumentImpl & rSrc)
541 {
542     mCpAndFcs = rSrc.mCpAndFcs;
543 
544     mpCHPFKPCache = rSrc.mpCHPFKPCache;
545     mpPAPFKPCache = rSrc.mpPAPFKPCache;
546 
547     mpStream = rSrc.mpStream;
548     mpTableStream = rSrc.mpTableStream;
549     mpDataStream = rSrc.mpDataStream;
550     mpDocStream = rSrc.mpDocStream;
551     mpCompObjStream = rSrc.mpCompObjStream;
552 
553     mpPieceTable = rSrc.mpPieceTable;
554 
555     mpBinTableCHPX = rSrc.mpBinTableCHPX;
556     mpBinTablePAPX = rSrc.mpBinTablePAPX;
557 
558     mpSEDs = rSrc.mpSEDs;
559 
560     mpFib = rSrc.mpFib;
561 
562     mpHeaderOffsets = rSrc.mpHeaderOffsets;
563     mpFootnoteHelper = rSrc.mpFootnoteHelper;
564     mpEndnoteHelper = rSrc.mpEndnoteHelper;
565     mpAnnotationHelper = rSrc.mpAnnotationHelper;
566     mpShapeHelper = rSrc.mpShapeHelper;
567     mpBreakHelper = rSrc.mpBreakHelper;
568 
569     mpBookmarkHelper = rSrc.mpBookmarkHelper;
570 
571     mpDffBlock = rSrc.mpDffBlock;
572     mpTextBoxStories = rSrc.mpTextBoxStories;
573 
574     mDocumentEndCpAndFc = rSrc.mDocumentEndCpAndFc;
575     mFootnoteEndCpAndFc = rSrc.mFootnoteEndCpAndFc;
576 
577     return *this;
578 }
579 
getType() const580 string WW8DocumentImpl::getType() const
581 {
582     return "WW8DocumentImpl";
583 }
584 
parseBinTableCpAndFcs(WW8BinTable & rTable,PropertyType eType_)585 void WW8DocumentImpl::parseBinTableCpAndFcs(WW8BinTable & rTable,
586                                             PropertyType eType_)
587 {
588     //clog << "<bintable type=\"" << propertyTypeToString(eType_) << "\">" << endl;
589     for (sal_uInt32 i = 0; i < rTable.getEntryCount(); i++)
590     {
591 #if 0
592         char sBuffer[255];
593         snprintf(sBuffer, 255, "%ld", i);
594         char sBufferPageNum[255];
595         snprintf(sBufferPageNum, 255, "%ld", rTable.getPageNumber(i));
596 #endif
597         Fc aFcFromTable(rTable.getFc(i));
598 
599         if (aFcFromTable < mpPieceTable->getFirstFc())
600             aFcFromTable = mpPieceTable->getFirstFc();
601 
602         bool bComplex = mpPieceTable->isComplex(aFcFromTable);
603         aFcFromTable.setComplex(bComplex);
604 
605         //clog << "<entry fc=\"" << aFcFromTable.toString() << "\">" << endl;
606 
607         try
608         {
609             Cp aCpFromTable(mpPieceTable->fc2cp(aFcFromTable));
610             CpAndFc aCpAndFcFromTable(aCpFromTable, aFcFromTable, eType_);
611 
612             mCpAndFcs.insert(aCpAndFcFromTable);
613 
614             WW8FKP::Pointer_t pFKP;
615 
616             switch (eType_)
617             {
618             case PROP_CHP:
619                 pFKP = getFKPCHPX(rTable.getPageNumber(i),
620                                   aCpAndFcFromTable.isComplex());
621 
622                 break;
623 
624             case PROP_PAP:
625                 pFKP = getFKPPAPX(rTable.getPageNumber(i),
626                                   aCpAndFcFromTable.isComplex());
627 
628                 break;
629             default:
630                 break;
631             }
632 
633             for (sal_uInt32 n = 0; n < pFKP->getEntryCount(); n++)
634             {
635                 Fc aFc = pFKP->getFc(n);
636 
637                 if (aFc < mpPieceTable->getFirstFc())
638                     aFc = mpPieceTable->getFirstFc();
639 
640                 bool bComplexFKP = mpPieceTable->isComplex(aFc);
641                 aFc.setComplex(bComplexFKP);
642 
643                 //clog << "<fkpentry fc=\"" << aFc.toString() << "\"/>" << endl;
644 
645                 try
646                 {
647                     Cp aCp = mpPieceTable->fc2cp(aFc);
648 
649                     CpAndFc aCpAndFc(aCp, aFc, eType_);
650 
651                     mCpAndFcs.insert(aCpAndFc);
652 
653                     //clog << aCpAndFc << endl;
654                 }
655                 catch (ExceptionNotFound e)
656                 {
657                     clog << e.getText() << endl;
658                 }
659             }
660         }
661         catch (ExceptionNotFound e)
662         {
663             clog << e.getText() << endl;
664         }
665 
666         //clog << "</entry>" << endl;
667     }
668 
669     //clog << "</bintable>" << endl;
670 }
671 
getSubStream(const::rtl::OUString & sId) const672 WW8Stream::Pointer_t WW8DocumentImpl::getSubStream
673 (const ::rtl::OUString & sId) const
674 {
675     return mpStream->getSubStream(sId);
676 }
677 
getSubDocument(SubDocumentId)678 WW8Document::Pointer_t WW8DocumentImpl::getSubDocument(SubDocumentId /*nId*/)
679 {
680     return WW8Document::Pointer_t(new WW8DocumentImpl(*this));
681 }
682 
683 WW8DocumentIterator::Pointer_t
getIterator(const CpAndFc & rCpAndFc)684 WW8DocumentImpl::getIterator(const CpAndFc & rCpAndFc)
685 {
686     return WW8DocumentIterator::Pointer_t
687         (new WW8DocumentIteratorImpl(this, rCpAndFc));
688 }
689 
begin()690 WW8DocumentIterator::Pointer_t WW8DocumentImpl::begin()
691 {
692     return getIterator(getFirstCp());
693 }
694 
end()695 WW8DocumentIterator::Pointer_t WW8DocumentImpl::end()
696 {
697     return getIterator(getLastCp());
698 }
699 
getDocStream() const700 WW8Stream::Pointer_t WW8DocumentImpl::getDocStream() const
701 {
702     return mpDocStream;
703 }
704 
getDataStream() const705 WW8Stream::Pointer_t WW8DocumentImpl::getDataStream() const
706 {
707     return mpDataStream;
708 }
709 
getByteLength(const CpAndFc & rCpAndFc) const710 sal_uInt32 WW8DocumentImpl::getByteLength(const CpAndFc & rCpAndFc) const
711 {
712     CpAndFc aEnd = getNextCp(rCpAndFc);
713 
714     sal_uInt32 nResult = 3;
715 
716     if (rCpAndFc < aEnd)
717         nResult = (aEnd - rCpAndFc) *
718             (mpPieceTable->isComplex(rCpAndFc.getCp()) ? 1 : 2);
719 
720     return nResult;
721 }
722 
723 WW8Stream::Sequence
getText(const CpAndFc & rStart)724 WW8DocumentImpl::getText(const CpAndFc & rStart)
725 {
726     return mpDocStream->get(rStart.getFc().get(), getByteLength(rStart));
727 }
728 
getFirstCp() const729 const CpAndFc & WW8DocumentImpl::getFirstCp() const
730 {
731     return mCpAndFcStart;
732 }
733 
getLastCp() const734 const CpAndFc & WW8DocumentImpl::getLastCp() const
735 {
736     return mCpAndFcEnd;
737 }
738 
getDocumentEndCp() const739 CpAndFc WW8DocumentImpl::getDocumentEndCp() const
740 {
741     return mDocumentEndCpAndFc;
742 }
743 
getFootnodeEndCp() const744 CpAndFc WW8DocumentImpl::getFootnodeEndCp() const
745 {
746     return mFootnoteEndCpAndFc;
747 }
748 
getHeaderEndCp() const749 CpAndFc WW8DocumentImpl::getHeaderEndCp() const
750 {
751     return mHeaderEndCpAndFc;
752 }
753 
getAnnotationEndCp() const754 CpAndFc WW8DocumentImpl::getAnnotationEndCp() const
755 {
756     return mAnnotationEndCpAndFc;
757 }
758 
getEndnoteEndCp() const759 CpAndFc WW8DocumentImpl::getEndnoteEndCp() const
760 {
761     return mEndnoteEndCpAndFc;
762 }
763 
getTextboxEndCp() const764 CpAndFc WW8DocumentImpl::getTextboxEndCp() const
765 {
766     return mTextboxEndCpAndFc;
767 }
768 
getTextboxHeaderEndCp() const769 CpAndFc WW8DocumentImpl::getTextboxHeaderEndCp() const
770 {
771     return mTextboxHeaderEndCpAndFc;
772 }
773 
getNextCp(const CpAndFc & rCpAndFc) const774 CpAndFc WW8DocumentImpl::getNextCp(const CpAndFc & rCpAndFc) const
775 {
776     CpAndFc aResult = mCpAndFcEnd;
777     CpAndFcs::const_iterator aIt = mCpAndFcs.find(rCpAndFc);
778 
779     if (aIt != mCpAndFcs.end())
780     {
781         aIt++;
782 
783         if (aIt != mCpAndFcs.end())
784             aResult = *aIt;
785     }
786     else
787         throw ExceptionNotFound("getNextCp: " + rCpAndFc.toString());
788 
789     return aResult;
790 }
791 
getPrevCp(const CpAndFc & rCpAndFc) const792 CpAndFc WW8DocumentImpl::getPrevCp(const CpAndFc & rCpAndFc) const
793 {
794     CpAndFc aResult = mCpAndFcStart;
795 
796     CpAndFcs::const_iterator aIt = mCpAndFcs.find(CpAndFc(rCpAndFc));
797 
798     if (aIt != mCpAndFcs.end() && aIt != mCpAndFcs.begin())
799     {
800         aIt--;
801 
802         aResult = *aIt;
803     }
804     else
805         throw ExceptionNotFound("getPrevCp: " + rCpAndFc.toString());
806 
807     return aResult;
808 }
809 
getFKP(const CpAndFc & rCpAndFc)810 WW8FKP::Pointer_t WW8DocumentImpl::getFKP(const CpAndFc & rCpAndFc)
811 {
812     WW8FKP::Pointer_t pResult;
813 
814     sal_uInt32 nPageNumber = 0;
815 
816     switch (rCpAndFc.getType())
817     {
818     case PROP_PAP:
819         {
820             nPageNumber =
821                 mpBinTablePAPX->getPageNumber(rCpAndFc.getFc());
822 
823             pResult = getFKPPAPX(nPageNumber, rCpAndFc.isComplex());
824         }
825         break;
826     case PROP_CHP:
827         {
828             nPageNumber =
829                 mpBinTableCHPX->getPageNumber(rCpAndFc.getFc());
830 
831             pResult = getFKPCHPX(nPageNumber, rCpAndFc.isComplex());
832         }
833         break;
834     default:
835         break;
836     }
837 
838     if (pResult.get() != NULL)
839         pResult->setDocument(this);
840 
841     return pResult;
842 }
843 
getFKPCHPX(sal_uInt32 nIndex,bool bComplex)844 WW8FKP::Pointer_t WW8DocumentImpl::getFKPCHPX(sal_uInt32 nIndex,
845                                               bool bComplex)
846 {
847     return mpCHPFKPCache->get(nIndex, bComplex);
848 }
849 
getFKPPAPX(sal_uInt32 nIndex,bool bComplex)850 WW8FKP::Pointer_t WW8DocumentImpl::getFKPPAPX(sal_uInt32 nIndex,
851                                               bool bComplex)
852 {
853     return mpPAPFKPCache->get(nIndex, bComplex);
854 }
855 
getProperties(const CpAndFc & rCpAndFc)856 writerfilter::Reference<Properties>::Pointer_t WW8DocumentImpl::getProperties
857 (const CpAndFc & rCpAndFc)
858 {
859     writerfilter::Reference<Properties>::Pointer_t pResult;
860 
861     switch (rCpAndFc.getType())
862     {
863     case PROP_CHP:
864     case PROP_PAP:
865         {
866             try
867             {
868                 WW8FKP::Pointer_t pFKP = getFKP(rCpAndFc);
869 
870                 pResult = pFKP->getProperties(rCpAndFc.getFc());
871             }
872             catch (ExceptionOutOfBounds e)
873             {
874             }
875         }
876 
877         break;
878 
879     case PROP_SEC:
880         {
881             pResult = writerfilter::Reference<Properties>::Pointer_t
882                 (getSED(rCpAndFc));
883         }
884 
885         break;
886 
887     case PROP_FOOTNOTE:
888         {
889             pResult = writerfilter::Reference<Properties>::Pointer_t
890                 (mpFootnoteHelper->getRef(rCpAndFc));
891         }
892         break;
893 
894     case PROP_ENDNOTE:
895         {
896             pResult = writerfilter::Reference<Properties>::Pointer_t
897                 (mpEndnoteHelper->getRef(rCpAndFc));
898         }
899         break;
900 
901     case PROP_ANNOTATION:
902         {
903             pResult = writerfilter::Reference<Properties>::Pointer_t
904                 (mpAnnotationHelper->getRef(rCpAndFc));
905         }
906         break;
907 
908     case PROP_BOOKMARKSTART:
909     case PROP_BOOKMARKEND:
910         {
911             pResult = getBookmark(rCpAndFc);
912         }
913 
914         break;
915     case PROP_FLD:
916         {
917             pResult = getField(rCpAndFc);
918 
919             mpFLD = mpFieldHelper->getWW8FLD(rCpAndFc);
920         }
921 
922         break;
923     case PROP_SHP:
924         {
925             pResult = getShape(rCpAndFc);
926         }
927         break;
928     case PROP_BRK:
929         {
930             pResult = getBreak(rCpAndFc);
931         }
932         break;
933     default:
934         break;
935     }
936 
937     return pResult;
938 }
939 
940 writerfilter::Reference<Stream>::Pointer_t
getSubDocument(const CpAndFc & rCpAndFc)941 WW8DocumentImpl::getSubDocument(const CpAndFc & rCpAndFc)
942 {
943     writerfilter::Reference<Stream>::Pointer_t pResult;
944 
945     switch (rCpAndFc.getType())
946     {
947     case PROP_FOOTNOTE:
948         pResult = getFootnote(rCpAndFc);
949         break;
950 
951     case PROP_ENDNOTE:
952         pResult = getEndnote(rCpAndFc);
953         break;
954 
955     case PROP_ANNOTATION:
956         pResult = getAnnotation(rCpAndFc);
957         break;
958 
959     default:
960         break;
961     }
962 
963     return pResult;
964 }
965 
getSED(const CpAndFc & rCpAndFc) const966 WW8SED * WW8DocumentImpl::getSED(const CpAndFc & rCpAndFc) const
967 {
968     WW8SED * pResult = mpSEDs->getEntryByFc(rCpAndFc.getCp().get());
969 
970     pResult->setDoc(const_cast<const WW8DocumentImpl *>(this));
971 
972     return pResult;
973 }
974 
getListTplcs() const975 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getListTplcs() const
976 {
977     writerfilter::Reference<Table>::Pointer_t pResult;
978 
979     if (mpFibRgFcLcb2000.get() != NULL &&
980         mpFibRgFcLcb2000->get_fcSttbRgtplc() != 0 &&
981         mpFibRgFcLcb2000->get_lcbSttbRgtplc() != 0)
982     {
983         WW8SttbRgtplc * pSttbRgtplc =
984         new WW8SttbRgtplc(*mpTableStream,
985                           mpFibRgFcLcb2000->get_fcSttbRgtplc(),
986                           mpFibRgFcLcb2000->get_lcbSttbRgtplc());
987 
988         pResult = writerfilter::Reference<Table>::Pointer_t(pSttbRgtplc);
989     }
990 
991     return pResult;
992 }
993 
getListTable() const994 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getListTable() const
995 {
996     writerfilter::Reference<Table>::Pointer_t pResult;
997 
998     if (mpFib->get_fcPlcfLst() != 0 && mpFib->get_lcbPlcfLst() > 0)
999     {
1000         try
1001         {
1002             WW8ListTable * pList = new WW8ListTable(*mpTableStream,
1003                                                     mpFib->get_fcPlcfLst(),
1004                                                     mpFib->get_fcPlfLfo() -
1005                                                     mpFib->get_fcPlcfLst());
1006 
1007             pList->setPayloadOffset(mpFib->get_lcbPlcfLst());
1008             pList->initPayload();
1009 
1010             pResult = writerfilter::Reference<Table>::Pointer_t(pList);
1011         }
1012         catch (ExceptionOutOfBounds aException) {
1013         }
1014     }
1015 
1016     return pResult;
1017 }
1018 
getLFOTable() const1019 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getLFOTable() const
1020 {
1021     writerfilter::Reference<Table>::Pointer_t pResult;
1022 
1023     if (mpFib->get_fcPlfLfo() != 0 && mpFib->get_lcbPlfLfo() > 0)
1024     {
1025         try
1026         {
1027             WW8LFOTable * pLFOs = new WW8LFOTable(*mpTableStream,
1028                                                   mpFib->get_fcPlfLfo(),
1029                                                   mpFib->get_lcbPlfLfo());
1030 
1031             pLFOs->setPayloadOffset(mpFib->get_lcbPlcfLst());
1032             pLFOs->initPayload();
1033 
1034             pResult = writerfilter::Reference<Table>::Pointer_t(pLFOs);
1035         }
1036         catch (Exception e)
1037         {
1038             clog << e.getText() << endl;
1039         }
1040     }
1041 
1042     return pResult;
1043 }
1044 
getFontTable() const1045 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getFontTable() const
1046 {
1047     writerfilter::Reference<Table>::Pointer_t pResult;
1048 
1049     if (mpFib->get_fcSttbfffn() != 0 && mpFib->get_lcbSttbfffn() > 0)
1050     {
1051         WW8FontTable * pFonts = new WW8FontTable(*mpTableStream,
1052                                                  mpFib->get_fcSttbfffn(),
1053                                                  mpFib->get_lcbSttbfffn());
1054 
1055         pFonts->initPayload();
1056 
1057         pResult = writerfilter::Reference<Table>::Pointer_t(pFonts);
1058     }
1059 
1060     return pResult;
1061 }
1062 
getStyleSheet() const1063 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getStyleSheet() const
1064 {
1065     writerfilter::Reference<Table>::Pointer_t pResult;
1066 
1067     if (mpFib->get_lcbStshf() > 0)
1068     {
1069         WW8StyleSheet * pStyles = new WW8StyleSheet(*mpTableStream,
1070                                                     mpFib->get_fcStshf(),
1071                                                     mpFib->get_lcbStshf());
1072 
1073         pStyles->initPayload();
1074 
1075         pResult = writerfilter::Reference<Table>::Pointer_t(pStyles);
1076     }
1077 
1078     return pResult;
1079 }
1080 
getAssocTable() const1081 writerfilter::Reference<Table>::Pointer_t WW8DocumentImpl::getAssocTable() const
1082 {
1083     writerfilter::Reference<Table>::Pointer_t pResult;
1084 
1085     if (mpFib->get_lcbSttbfAssoc() > 0)
1086     {
1087         WW8Sttbf::Pointer_t pSttbfAssoc
1088             (new WW8Sttbf(*mpTableStream,
1089                           mpFib->get_fcSttbfAssoc(),
1090                           mpFib->get_lcbSttbfAssoc()));
1091 
1092         pResult = writerfilter::Reference<Table>::Pointer_t
1093             (new WW8SttbTableResource(pSttbfAssoc));
1094     }
1095 
1096     return pResult;
1097 }
1098 
getHeaderCount() const1099 sal_uInt32 WW8DocumentImpl::getHeaderCount() const
1100 {
1101     sal_uInt32 nResult = 0;
1102     sal_uInt32 nLcbPlcfhdd = mpFib->get_lcbPlcfhdd();
1103 
1104     if (nLcbPlcfhdd > 4)
1105         nResult = (nLcbPlcfhdd / 4) - 1;
1106 
1107     return nResult;
1108 }
1109 
getHeaderCpAndFc(sal_uInt32 nPos)1110 CpAndFc WW8DocumentImpl::getHeaderCpAndFc(sal_uInt32 nPos)
1111 {
1112     sal_uInt32 nCount = getHeaderCount();
1113 
1114     // There are getHeaderCount() + 1 entries in mpHeaderOffsets => greater
1115     if (nPos > nCount)
1116         throw ExceptionNotFound("getHeaderCpAndFc");
1117 
1118     if (nPos == nCount)
1119         return mHeaderEndCpAndFc;
1120     else
1121     {
1122         Cp aCp(getFootnodeEndCp().getCp() + mpHeaderOffsets->getU32(nPos * 4));
1123         Fc aFc(mpPieceTable->cp2fc(aCp));
1124         CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
1125 
1126         return aCpAndFc;
1127     }
1128 
1129 }
1130 
getHeader(sal_uInt32 nPos)1131 writerfilter::Reference<Stream>::Pointer_t WW8DocumentImpl::getHeader(sal_uInt32 nPos)
1132 {
1133     // There are getHeaderCount() headers => greater or equal
1134     if (nPos >= getHeaderCount())
1135         throw ExceptionNotFound("getHeader");
1136 
1137     writerfilter::Reference<Stream>::Pointer_t pResult;
1138 
1139     CpAndFc aCpAndFcStart(getHeaderCpAndFc(nPos));
1140     CpAndFc aCpAndFcEnd(getHeaderCpAndFc(nPos + 1));
1141 
1142 #if 0
1143     sal_uInt32 nEquals = 1;
1144     while (aCpAndFcEnd == aCpAndFcStart && nPos + nEquals < getHeaderCount())
1145     {
1146         ++nEquals;
1147 
1148         aCpAndFcEnd = getHeaderCpAndFc(nPos + nEquals);
1149     }
1150 #endif
1151 
1152     if (aCpAndFcStart < aCpAndFcEnd)
1153         pResult = writerfilter::Reference<Stream>::Pointer_t
1154             (new WW8DocumentImpl(*this, aCpAndFcStart, aCpAndFcEnd));
1155 
1156     return pResult;
1157 }
1158 
getFootnoteCount() const1159 sal_uInt32 WW8DocumentImpl::getFootnoteCount() const
1160 {
1161     return (mpFootnoteHelper.get() != NULL) ? mpFootnoteHelper->getCount() : 0;
1162 }
1163 
1164 writerfilter::Reference<Stream>::Pointer_t
getFootnote(sal_uInt32 nPos)1165 WW8DocumentImpl::getFootnote(sal_uInt32 nPos)
1166 {
1167     writerfilter::Reference<Stream>::Pointer_t pResult;
1168 
1169     if (! bSubDocument)
1170         pResult = mpFootnoteHelper->get(nPos);
1171 
1172     return pResult;
1173 }
1174 
1175 writerfilter::Reference<Stream>::Pointer_t
getFootnote(const CpAndFc & rCpAndFc)1176 WW8DocumentImpl::getFootnote(const CpAndFc & rCpAndFc)
1177 {
1178     writerfilter::Reference<Stream>::Pointer_t pResult;
1179 
1180     if (! bSubDocument)
1181         pResult = mpFootnoteHelper->get(rCpAndFc);
1182 
1183     return pResult;
1184 }
1185 
getEndnoteCount() const1186 sal_uInt32 WW8DocumentImpl::getEndnoteCount() const
1187 {
1188     return mpEndnoteHelper.get() != NULL ? mpEndnoteHelper->getCount() : 0;
1189 }
1190 
1191 writerfilter::Reference<Stream>::Pointer_t
getEndnote(sal_uInt32 nPos)1192 WW8DocumentImpl::getEndnote(sal_uInt32 nPos)
1193 {
1194     writerfilter::Reference<Stream>::Pointer_t pResult;
1195 
1196     if (! bSubDocument)
1197         pResult = mpEndnoteHelper->get(nPos);
1198 
1199     return pResult;
1200 }
1201 
1202 writerfilter::Reference<Stream>::Pointer_t
getEndnote(const CpAndFc & rCpAndFc)1203 WW8DocumentImpl::getEndnote(const CpAndFc & rCpAndFc)
1204 {
1205     writerfilter::Reference<Stream>::Pointer_t pResult;
1206 
1207     if (! bSubDocument)
1208         pResult = mpEndnoteHelper->get(rCpAndFc);
1209 
1210     return pResult;
1211 }
1212 
getAnnotationCount() const1213 sal_uInt32 WW8DocumentImpl::getAnnotationCount() const
1214 {
1215     return mpAnnotationHelper.get() != NULL ?
1216         mpAnnotationHelper->getCount() : 0;
1217 }
1218 
1219 writerfilter::Reference<Stream>::Pointer_t
getAnnotation(sal_uInt32 nPos)1220 WW8DocumentImpl::getAnnotation(sal_uInt32 nPos)
1221 {
1222     writerfilter::Reference<Stream>::Pointer_t pResult;
1223 
1224     if (! bSubDocument)
1225         pResult = mpAnnotationHelper->get(nPos);
1226 
1227     return pResult;
1228 }
1229 
1230 writerfilter::Reference<Stream>::Pointer_t
getAnnotation(const CpAndFc & rCpAndFc)1231 WW8DocumentImpl::getAnnotation(const CpAndFc & rCpAndFc)
1232 {
1233     writerfilter::Reference<Stream>::Pointer_t pResult;
1234 
1235     if (! bSubDocument)
1236         pResult = mpAnnotationHelper->get(rCpAndFc);
1237 
1238     return pResult;
1239 }
1240 
1241 writerfilter::Reference<Properties>::Pointer_t
getBookmark(const CpAndFc & rCpAndFc) const1242 WW8DocumentImpl::getBookmark(const CpAndFc & rCpAndFc) const
1243 {
1244     return mpBookmarkHelper->getBookmark(rCpAndFc);
1245 }
1246 
1247 writerfilter::Reference<Properties>::Pointer_t
getShape(const CpAndFc & rCpAndFc) const1248 WW8DocumentImpl::getShape(const CpAndFc & rCpAndFc) const
1249 {
1250     return mpShapeHelper->getShape(rCpAndFc);
1251 }
1252 
1253 writerfilter::Reference<Properties>::Pointer_t
getShape(sal_uInt32 nSpid)1254 WW8DocumentImpl::getShape(sal_uInt32 nSpid)
1255 {
1256     writerfilter::Reference<Properties>::Pointer_t pResult;
1257     DffRecord::Pointer_t pShape = mpDffBlock->getShape(nSpid);
1258 
1259     if (pShape.get() != NULL)
1260     {
1261         DffSpContainer * pTmp = new DffSpContainer(*pShape);
1262         pTmp->setDocument(this);
1263 
1264         pResult = writerfilter::Reference<Properties>::Pointer_t(pTmp);
1265     }
1266 
1267     return pResult;
1268 }
1269 
1270 writerfilter::Reference<Properties>::Pointer_t
getBreak(const CpAndFc & rCpAndFc) const1271 WW8DocumentImpl::getBreak(const CpAndFc & rCpAndFc) const
1272 {
1273     return mpBreakHelper->getBreak(rCpAndFc);
1274 }
1275 
1276 writerfilter::Reference<Properties>::Pointer_t
getBlip(sal_uInt32 nBid)1277 WW8DocumentImpl::getBlip(sal_uInt32 nBid)
1278 {
1279     writerfilter::Reference<Properties>::Pointer_t pResult;
1280 
1281     if( bool(mpDffBlock))
1282     {
1283         DffRecord::Pointer_t pDffRecord(mpDffBlock->getBlip(nBid));
1284 
1285         if (pDffRecord.get() != NULL)
1286         {
1287             DffBSE * pBlip = new DffBSE(*pDffRecord);
1288 
1289             if (pBlip != NULL)
1290             pResult = writerfilter::Reference<Properties>::Pointer_t(pBlip);
1291         }
1292     }
1293 
1294     return pResult;
1295 }
1296 
1297 writerfilter::Reference<Properties>::Pointer_t
getField(const CpAndFc & rCpAndFc) const1298 WW8DocumentImpl::getField(const CpAndFc & rCpAndFc) const
1299 {
1300     return mpFieldHelper->getField(rCpAndFc);
1301 }
1302 
1303 writerfilter::Reference<Properties>::Pointer_t
getDocumentProperties() const1304 WW8DocumentImpl::getDocumentProperties() const
1305 {
1306     writerfilter::Reference<Properties>::Pointer_t pResult;
1307 
1308     if (mpFib->get_lcbDop() > 0)
1309     {
1310         pResult.reset(new WW8DopBase(*mpTableStream, mpFib->get_fcDop(), mpFib->get_lcbDop()));
1311     }
1312 
1313     return pResult;
1314 }
1315 
getCurrentFLD() const1316 WW8FLD::Pointer_t WW8DocumentImpl::getCurrentFLD() const
1317 {
1318     return mpFLD;
1319 }
1320 
getPicLocation() const1321 sal_uInt32 WW8DocumentImpl::getPicLocation() const
1322 {
1323     return mfcPicLoc;
1324 }
1325 
setPicLocation(sal_uInt32 fcPicLoc)1326 void WW8DocumentImpl::setPicLocation(sal_uInt32 fcPicLoc)
1327 {
1328     mfcPicLoc = fcPicLoc;
1329 }
1330 
isPicData()1331 bool WW8DocumentImpl::isPicData()
1332 {
1333     return mbPicIsData;
1334 }
1335 
setPicIsData(bool bPicIsData)1336 void WW8DocumentImpl::setPicIsData(bool bPicIsData)
1337 {
1338     mbPicIsData = bPicIsData;
1339 }
1340 
1341 writerfilter::Reference<Stream>::Pointer_t
getTextboxText(sal_uInt32 nShpId) const1342 WW8DocumentImpl::getTextboxText(sal_uInt32 nShpId) const
1343 {
1344     writerfilter::Reference<Stream>::Pointer_t pResult;
1345 
1346     if (mpTextBoxStories.get() != NULL)
1347     {
1348         sal_uInt32 nCount = mpTextBoxStories->getEntryCount();
1349 
1350         sal_uInt32 n = 0;
1351         while (n < nCount)
1352         {
1353             WW8FTXBXS * pTextboxStory = mpTextBoxStories->getEntryPointer(n);
1354 
1355             if (pTextboxStory->get_lid() == nShpId)
1356                 break;
1357 
1358             ++n;
1359         }
1360 
1361         if (n < nCount)
1362         {
1363             Cp aCpStart(mpTextBoxStories->getFc(n));
1364             aCpStart += getEndnoteEndCp().getCp().get();
1365             CpAndFc aCpAndFcStart =
1366                 mpPieceTable->createCpAndFc(aCpStart, PROP_DOC);
1367             Cp aCpEnd(mpTextBoxStories->getFc(n + 1));
1368             aCpEnd += getEndnoteEndCp().getCp().get();
1369             CpAndFc aCpAndFcEnd = mpPieceTable->createCpAndFc(aCpEnd, PROP_DOC);
1370 
1371             pResult = writerfilter::Reference<Stream>::Pointer_t
1372                 (new WW8DocumentImpl(*this, aCpAndFcStart, aCpAndFcEnd));
1373         }
1374     }
1375 
1376     return pResult;
1377 }
1378 
lcl_headerQName(sal_uInt32 nIndex)1379 Id lcl_headerQName(sal_uInt32 nIndex)
1380 {
1381     Id qName = NS_rtf::LN_header;
1382 
1383     if (nIndex > 5)
1384     {
1385         switch ((nIndex - 6) % 6)
1386         {
1387         case 0:
1388             qName = NS_rtf::LN_headerl;
1389 
1390             break;
1391         case 1:
1392             qName = NS_rtf::LN_headerr;
1393 
1394             break;
1395         case 2:
1396             qName = NS_rtf::LN_footerl;
1397 
1398             break;
1399         case 3:
1400             qName = NS_rtf::LN_footerr;
1401 
1402             break;
1403         case 4:
1404             qName = NS_rtf::LN_headerf;
1405 
1406             break;
1407         case 5:
1408             qName = NS_rtf::LN_footerf;
1409 
1410             break;
1411         }
1412     }
1413 
1414     return qName;
1415 }
1416 
cp2fc(const Cp & cp) const1417 Fc WW8DocumentImpl::cp2fc(const Cp & cp) const
1418 {
1419     return mpPieceTable->cp2fc(cp);
1420 }
1421 
fc2cp(const Fc & fc) const1422 Cp WW8DocumentImpl::fc2cp(const Fc & fc) const
1423 {
1424     return mpPieceTable->fc2cp(fc);
1425 }
1426 
getCpAndFc(const Cp & cp,PropertyType type) const1427 CpAndFc WW8DocumentImpl::getCpAndFc(const Cp & cp, PropertyType type) const
1428 {
1429     Fc aFc = cp2fc(cp);
1430 
1431     return CpAndFc(cp, aFc, type);
1432 }
1433 
getCpAndFc(const Fc & fc,PropertyType type) const1434 CpAndFc WW8DocumentImpl::getCpAndFc(const Fc & fc, PropertyType type) const
1435 {
1436     Cp aCp = fc2cp(fc);
1437 
1438     return CpAndFc(aCp, fc, type);
1439 }
1440 
resolvePicture(Stream & rStream)1441 void WW8DocumentImpl::resolvePicture(Stream & rStream)
1442 {
1443     WW8Stream::Pointer_t pStream = getDataStream();
1444 
1445     if (pStream.get() != NULL)
1446     {
1447         WW8StructBase aStruct(*pStream, mfcPicLoc, 4);
1448         sal_uInt32 nCount = aStruct.getU32(0);
1449 
1450         {
1451             WW8PICF * pPicf = new WW8PICF(*pStream, mfcPicLoc, nCount);
1452             pPicf->setDocument(this);
1453 
1454             writerfilter::Reference<Properties>::Pointer_t pProps(pPicf);
1455 
1456             rStream.props(pProps);
1457         }
1458     }
1459 }
1460 
resolveSpecialChar(sal_uInt32 nChar,Stream & rStream)1461 void WW8DocumentImpl::resolveSpecialChar(sal_uInt32 nChar, Stream & rStream)
1462 {
1463     switch (nChar)
1464     {
1465     case 0x1:
1466         resolvePicture(rStream);
1467         break;
1468     default:
1469         break;
1470     }
1471 }
1472 
text(Stream & rStream,const sal_uInt8 * data,size_t len)1473 void WW8DocumentImpl::text(Stream & rStream, const sal_uInt8 * data, size_t len)
1474 {
1475 #ifdef DEBUG_ELEMENT
1476     ::rtl::OUString sText( (const sal_Char*) data, len, RTL_TEXTENCODING_MS_1252 );
1477     debug_logger->startElement("text");
1478     debug_logger->chars(OUStringToOString(sText, RTL_TEXTENCODING_ASCII_US).getStr());
1479     debug_logger->endElement("text");
1480 #endif
1481     rStream.text(data, len);
1482 }
1483 
utext(Stream & rStream,const sal_uInt8 * data,size_t len)1484 void WW8DocumentImpl::utext(Stream & rStream, const sal_uInt8 * data, size_t len)
1485 {
1486 #ifdef DEBUG_ELEMENT
1487     debug_logger->startElement("utext");
1488 
1489     ::rtl::OUString sText;
1490     ::rtl::OUStringBuffer aBuffer = ::rtl:: OUStringBuffer(len);
1491     aBuffer.append( (const sal_Unicode *) data, len);
1492     sText = aBuffer.makeStringAndClear();
1493 
1494     debug_logger->chars(OUStringToOString(sText, RTL_TEXTENCODING_ASCII_US).getStr());
1495     debug_logger->endElement("utext");
1496 #endif
1497     rStream.utext(data, len);
1498 }
1499 
1500 
resolveText(WW8DocumentIterator::Pointer_t pIt,Stream & rStream)1501 void WW8DocumentImpl::resolveText(WW8DocumentIterator::Pointer_t pIt,
1502                                   Stream & rStream)
1503 {
1504     WW8Stream::Sequence aSeq = pIt->getText();
1505 
1506     sal_uInt32 nCount = aSeq.getCount();
1507     bool bComplex = pIt->isComplex();
1508 
1509     /*
1510       Assumption: Special characters are always at the beginning or end of a
1511       run.
1512      */
1513     if (nCount > 0)
1514     {
1515         if (nCount == 1)
1516             bComplex = true;
1517 
1518         if (bComplex)
1519         {
1520             sal_uInt32 nStartIndex = 0;
1521             sal_uInt32 nEndIndex = nCount - 1;
1522 
1523             sal_uInt32 nCharFirst = aSeq[0];
1524             sal_uInt32 nCharLast = aSeq[nEndIndex];
1525 
1526             if (isSpecial(nCharFirst))
1527             {
1528                 nStartIndex += 1;
1529                 resolveSpecialChar(nCharFirst, rStream);
1530                 text(rStream, &aSeq[0], 1);
1531             }
1532 
1533             if (!isSpecial(nCharLast))
1534                 nEndIndex += 1;
1535 
1536             if (nStartIndex < nEndIndex)
1537             {
1538                 sal_uInt32 nChars = nEndIndex - nStartIndex;
1539                 text(rStream, &aSeq[nStartIndex], nChars);
1540 
1541                 if (isSpecial(nCharLast))
1542                 {
1543                     resolveSpecialChar(nCharLast, rStream);
1544                     text(rStream, &aSeq[nEndIndex], 1);
1545                 }
1546             }
1547         }
1548         else
1549         {
1550             sal_uInt32 nStartIndex = 0;
1551             sal_uInt32 nEndIndex = nCount - 2;
1552 
1553             sal_uInt32 nCharFirst = aSeq[0] + (aSeq[1] << 8);
1554             sal_uInt32 nCharLast = aSeq[nEndIndex] + (aSeq[nEndIndex + 1]);
1555 
1556             if (isSpecial(nCharFirst))
1557             {
1558                 nStartIndex += 2;
1559                 resolveSpecialChar(nCharFirst, rStream);
1560                 utext(rStream, &aSeq[0], 1);
1561             }
1562 
1563             if (!isSpecial(nCharLast))
1564                 nEndIndex += 2;
1565 
1566             if (nStartIndex < nEndIndex)
1567             {
1568                 sal_uInt32 nChars = (nEndIndex - nStartIndex) / 2;
1569                 utext(rStream, &aSeq[nStartIndex], nChars);
1570 
1571                 if (isSpecial(nCharLast))
1572                 {
1573                     resolveSpecialChar(nCharLast, rStream);
1574                     utext(rStream, &aSeq[nEndIndex], 1);
1575                 }
1576             }
1577         }
1578     }
1579 }
1580 
startCharacterGroup(Stream & rStream)1581 void WW8DocumentImpl::startCharacterGroup(Stream & rStream)
1582 {
1583     if (mbInCharacterGroup)
1584         endCharacterGroup(rStream);
1585 
1586 #ifdef DEBUG_ELEMENT
1587     debug_logger->startElement("charactergroup");
1588 #endif
1589 
1590     rStream.startCharacterGroup();
1591     mbInCharacterGroup = true;
1592 }
1593 
endCharacterGroup(Stream & rStream)1594 void WW8DocumentImpl::endCharacterGroup(Stream & rStream)
1595 {
1596 #ifdef DEBUG_ELEMENT
1597     debug_logger->endElement("charactergroup");
1598 #endif
1599 
1600     rStream.endCharacterGroup();
1601     mbInCharacterGroup = false;
1602 }
1603 
startParagraphGroup(Stream & rStream)1604 void WW8DocumentImpl::startParagraphGroup(Stream & rStream)
1605 {
1606     if (mbInParagraphGroup)
1607         endParagraphGroup(rStream);
1608 
1609 #ifdef DEBUG_ELEMENT
1610     debug_logger->startElement("paragraphgroup");
1611 #endif
1612 
1613     rStream.startParagraphGroup();
1614     mbInParagraphGroup = true;
1615 }
1616 
endParagraphGroup(Stream & rStream)1617 void WW8DocumentImpl::endParagraphGroup(Stream & rStream)
1618 {
1619     if (mbInCharacterGroup)
1620         endCharacterGroup(rStream);
1621 
1622 #ifdef DEBUG_ELEMENT
1623     debug_logger->endElement("paragraphgroup");
1624 #endif
1625     rStream.endParagraphGroup();
1626     mbInParagraphGroup = false;
1627 }
1628 
startSectionGroup(Stream & rStream)1629 void WW8DocumentImpl::startSectionGroup(Stream & rStream)
1630 {
1631     if (mbInSection)
1632         endSectionGroup(rStream);
1633 
1634 #ifdef DEBUG_ELEMENT
1635     debug_logger->startElement("sectiongroup");
1636 #endif
1637 
1638     rStream.startSectionGroup();
1639     mbInSection = true;
1640 }
1641 
endSectionGroup(Stream & rStream)1642 void WW8DocumentImpl::endSectionGroup(Stream & rStream)
1643 {
1644     if (mbInParagraphGroup)
1645         endParagraphGroup(rStream);
1646 
1647 #ifdef DEBUG_ELEMENT
1648     debug_logger->endElement("sectiongroup");
1649 #endif
1650     rStream.endSectionGroup();
1651     mbInSection = false;
1652 }
1653 
resolve(Stream & rStream)1654 void WW8DocumentImpl::resolve(Stream & rStream)
1655 {
1656     if (! bSubDocument)
1657     {
1658 
1659         //mpPieceTable->dump(clog);
1660 
1661         //copy(mCpAndFcs.begin(), mCpAndFcs.end(), ostream_iterator<CpAndFc>(clog, ", "));
1662 
1663         //mpDocStream->dump(output);
1664 
1665         //output.addItem(mTextboxHeaderEndCpAndFc.toString());
1666 
1667 #if 1
1668         output.addItem("<substream-names>");
1669         output.addItem(mpStream->getSubStreamNames());
1670         output.addItem("</substream-names>");
1671 
1672         if (mpDocStream.get() != NULL)
1673         {
1674             mpDocStream->dump(output);
1675         }
1676 
1677         if (mpSummaryInformationStream.get() != NULL)
1678         {
1679             mpSummaryInformationStream->dump(output);
1680         }
1681 #endif
1682 
1683         writerfilter::Reference<Properties>::Pointer_t pFib
1684             (new WW8Fib(*mpFib));
1685         rStream.props(pFib);
1686 
1687         if (mpFibRgFcLcb2000.get() != NULL)
1688         {
1689             writerfilter::Reference<Properties>::Pointer_t pFibRgFcLcb2000
1690             (new WW8FibRgFcLcb2000(*mpFibRgFcLcb2000));
1691             rStream.props(pFibRgFcLcb2000);
1692         }
1693 
1694 #if 0
1695         if (mpTextBoxStories.get() != NULL)
1696         {
1697             output.addItem("<textbox.boxes>");
1698             mpTextBoxStories->dump(output);
1699             output.addItem("</textbox.boxes>");
1700         }
1701 #endif
1702         if (mpFib->get_lcbPlcftxbxBkd() > 0)
1703         {
1704             PLCF<WW8BKD> aPLCF(*mpTableStream,
1705                                mpFib->get_fcPlcftxbxBkd(),
1706                                mpFib->get_lcbPlcftxbxBkd());
1707 #if 0
1708             output.addItem("<textbox.breaks>");
1709             aPLCF.dump(output);
1710             output.addItem("</textbox.breaks>");
1711 #endif
1712         }
1713 
1714         if (mpDffBlock.get() != NULL)
1715         {
1716             DffBlock * pTmp = new DffBlock(*mpDffBlock);
1717             //pTmp->dump(clog);
1718             writerfilter::Reference<Properties>::Pointer_t pDffBlock =
1719                 writerfilter::Reference<Properties>::Pointer_t(pTmp);
1720 
1721             rStream.props(pDffBlock);
1722         }
1723 
1724         {
1725             rStream.info("headers");
1726             sal_uInt32 nHeaderCount = getHeaderCount();
1727             for (sal_uInt32 n = 0; n < nHeaderCount; ++n)
1728             {
1729                 rStream.info(getHeaderCpAndFc(n).toString());
1730             }
1731             rStream.info("/headers");
1732         }
1733 
1734 #if 0
1735         {
1736             sal_uInt32 nFootnoteCount = getFootnoteCount();
1737             for (sal_uInt32 n = 0; n < nFootnoteCount; ++n)
1738             {
1739                 //clog << "<footnote num=\"" << n << "\"/>" << endl;
1740 
1741                 writerfilter::Reference<Stream>::Pointer_t pFootnote(getFootnote(n));
1742 
1743                 if (pFootnote.get() != NULL)
1744                     rStream.substream(NS_rtf::LN_footnote, pFootnote);
1745             }
1746         }
1747         {
1748             sal_uInt32 nEndnoteCount = getEndnoteCount();
1749             for (sal_uInt32 n = 0; n < nEndnoteCount; ++n)
1750             {
1751                 //clog << "<endnote num=\"" << n << "\"/>" << endl;
1752 
1753                 writerfilter::Reference<Stream>::Pointer_t pEndnote(getEndnote(n));
1754 
1755                 if (pEndnote.get() != NULL)
1756                     rStream.substream(NS_rtf::LN_endnote, pEndnote);
1757             }
1758         }
1759 #endif
1760 
1761         writerfilter::Reference<Table>::Pointer_t pSttbRgtplc = getListTplcs();
1762 
1763         if (pSttbRgtplc.get() != NULL)
1764             rStream.table(NS_rtf::LN_SttbRgtplc, pSttbRgtplc);
1765 
1766         writerfilter::Reference<Table>::Pointer_t pFontTable = getFontTable();
1767 
1768         if (pFontTable.get() != NULL)
1769             rStream.table(NS_rtf::LN_FONTTABLE, pFontTable);
1770 
1771         try
1772         {
1773             writerfilter::Reference<Table>::Pointer_t pStyleSheet = getStyleSheet();
1774 
1775             if (pStyleSheet.get() != NULL)
1776                 rStream.table(NS_rtf::LN_STYLESHEET, pStyleSheet);
1777         }
1778         catch (Exception e)
1779         {
1780             clog << e.getText() << endl;
1781         }
1782 
1783         writerfilter::Reference<Table>::Pointer_t pAssocTable = getAssocTable();
1784 
1785         if (pAssocTable.get() != NULL)
1786             rStream.table(NS_rtf::LN_SttbAssoc, pAssocTable);
1787 
1788         writerfilter::Reference<Table>::Pointer_t pListTable = getListTable();
1789 
1790         if (pListTable.get() != NULL)
1791             rStream.table(NS_rtf::LN_LISTTABLE, pListTable);
1792 
1793         writerfilter::Reference<Table>::Pointer_t pLFOTable = getLFOTable();
1794 
1795         if (pLFOTable.get() != NULL)
1796             rStream.table(NS_rtf::LN_LFOTABLE, pLFOTable);
1797     }
1798 
1799     WW8DocumentIterator::Pointer_t pIt = begin();
1800     WW8DocumentIterator::Pointer_t pItEnd = end();
1801 
1802     mbInParagraphGroup = false;
1803     mbInCharacterGroup = false;
1804     mbInSection = false;
1805 
1806     sal_uInt32 nSectionIndex = 0;
1807 
1808     rStream.info(pIt->toString());
1809     rStream.info(pItEnd->toString());
1810 
1811     while (! pIt->equal(*pItEnd))
1812     {
1813         writerfilter::Reference<Properties>::Pointer_t
1814             pProperties(pIt->getProperties());
1815 
1816         switch (pIt->getPropertyType())
1817         {
1818         case PROP_FOOTNOTE:
1819             {
1820                 rStream.info(pIt->toString());
1821                 writerfilter::Reference<Stream>::Pointer_t
1822                     pFootnote(pIt->getSubDocument());
1823 
1824                 if (pFootnote.get() != NULL)
1825                 {
1826 #ifdef DEBUG_ELEMENT
1827                     debug_logger->startElement("substream");
1828 #endif
1829                     rStream.substream(NS_rtf::LN_footnote, pFootnote);
1830 #ifdef DEBUG_ELEMENT
1831                     debug_logger->endElement("substream");
1832 #endif
1833                 }
1834             }
1835             break;
1836         case PROP_ENDNOTE:
1837             {
1838                 rStream.info(pIt->toString());
1839                 writerfilter::Reference<Stream>::Pointer_t
1840                     pEndnote(pIt->getSubDocument());
1841 
1842                 if (pEndnote.get() != NULL)
1843                 {
1844 #ifdef DEBUG_ELEMENT
1845                     debug_logger->startElement("substream");
1846 #endif
1847                     rStream.substream(NS_rtf::LN_endnote, pEndnote);
1848 #ifdef DEBUG_ELEMENT
1849                     debug_logger->endElement("substream");
1850 #endif
1851                 }
1852             }
1853             break;
1854         case PROP_ANNOTATION:
1855             {
1856                 rStream.info(pIt->toString());
1857                 writerfilter::Reference<Stream>::Pointer_t
1858                     pAnnotation(pIt->getSubDocument());
1859 
1860                 if (pAnnotation.get() != NULL)
1861                 {
1862 #ifdef DEBUG_ELEMENT
1863                     debug_logger->startElement("substream");
1864 #endif
1865                     rStream.substream(NS_rtf::LN_annotation, pAnnotation);
1866 #ifdef DEBUG_ELEMENT
1867                     debug_logger->endElement("substream");
1868 #endif
1869                 }
1870             }
1871             break;
1872         case PROP_CHP:
1873             {
1874                 startCharacterGroup(rStream);
1875             }
1876 
1877             break;
1878         case PROP_PAP:
1879             {
1880                 startParagraphGroup(rStream);
1881                 rStream.info(pIt->toString());
1882             }
1883 
1884             break;
1885         case PROP_SEC:
1886             {
1887                 startSectionGroup(rStream);
1888                 rStream.info(pIt->toString());
1889 
1890                 if (nSectionIndex == 0)
1891                     rStream.props(getDocumentProperties());
1892 
1893                 sal_uInt32 nHeaderStartIndex = 6 + nSectionIndex * 6;
1894                 sal_uInt32 nHeaderEndIndex = nHeaderStartIndex + 6;
1895 
1896                 if (nHeaderStartIndex >= getHeaderCount())
1897                     nHeaderStartIndex = getHeaderCount();
1898 
1899                 if (nHeaderEndIndex >= getHeaderCount())
1900                     nHeaderEndIndex = getHeaderCount();
1901 
1902                 for (sal_uInt32 n = nHeaderStartIndex; n < nHeaderEndIndex; ++n)
1903                 {
1904                     writerfilter::Reference<Stream>::Pointer_t
1905                         pHeader(getHeader(n));
1906 
1907                     Id qName = lcl_headerQName(n);
1908 
1909                     if (pHeader.get() != NULL)
1910                         rStream.substream(qName, pHeader);
1911                 }
1912 
1913                 ++nSectionIndex;
1914             }
1915 
1916             break;
1917         default:
1918             rStream.info(pIt->toString());
1919         }
1920 
1921         if (pProperties.get() != NULL)
1922         {
1923 #ifdef DEBUG_PROPERTIES
1924             PropertySetToTagHandler aHandler(IdToString::Pointer_t(new WW8IdToString()));
1925             pProperties->resolve(aHandler);
1926             debug_logger->addTag(aHandler.getTag());
1927 #endif
1928 
1929             rStream.props(pProperties);
1930         }
1931 
1932         if (pIt->getPropertyType() == PROP_PAP)
1933         {
1934             startCharacterGroup(rStream);
1935         }
1936 
1937         resolveText(pIt, rStream);
1938 
1939         ++(*pIt);
1940     }
1941 
1942     if (mbInCharacterGroup)
1943         endCharacterGroup(rStream);
1944 
1945     if (mbInParagraphGroup)
1946         endParagraphGroup(rStream);
1947 
1948     if (mbInSection)
1949         endSectionGroup(rStream);
1950 
1951 }
1952 
1953 WW8Stream::Pointer_t
createStream(uno::Reference<uno::XComponentContext> rContext,uno::Reference<io::XInputStream> rStream)1954 WW8DocumentFactory::createStream(uno::Reference<uno::XComponentContext> rContext,
1955                                  uno::Reference<io::XInputStream> rStream)
1956 {
1957     return WW8Stream::Pointer_t(new WW8StreamImpl(rContext, rStream));
1958 }
1959 
1960 WW8Document *
createDocument(WW8Stream::Pointer_t rpStream)1961 WW8DocumentFactory::createDocument(WW8Stream::Pointer_t rpStream)
1962 {
1963     return new WW8DocumentImpl(rpStream);
1964 }
1965 
1966 writerfilter::Reference<Properties>::Pointer_t
get_sepx()1967 WW8SED::get_sepx()
1968 {
1969     writerfilter::Reference<Properties>::Pointer_t pResult;
1970 
1971     if (get_fcSepx() != 0xffffffff)
1972     {
1973         WW8StructBase aTmp(*mpDoc->getDocStream(), get_fcSepx(), 2);
1974         pResult = writerfilter::Reference<Properties>::Pointer_t
1975             (new WW8PropertySetImpl
1976              (*mpDoc->getDocStream(), get_fcSepx() + 2,
1977               (sal_uInt32) aTmp.getU16(0), false));
1978     }
1979 
1980     return pResult;
1981 }
1982 
insertCpAndFc(const CpAndFc & rCpAndFc)1983 void WW8DocumentImpl::insertCpAndFc(const CpAndFc & rCpAndFc)
1984 {
1985     mCpAndFcs.insert(rCpAndFc);
1986 }
1987 
propertyTypeToString(PropertyType nType)1988 string propertyTypeToString(PropertyType nType)
1989 {
1990     string result;
1991 
1992     switch (nType)
1993     {
1994     case PROP_SHP:
1995         result = "SHP";
1996 
1997         break;
1998     case PROP_FLD:
1999         result = "FLD";
2000 
2001         break;
2002     case PROP_BOOKMARKSTART:
2003         result = "BOOKMARKSTART";
2004 
2005         break;
2006     case PROP_BOOKMARKEND:
2007         result = "BOOKMARKEND";
2008 
2009         break;
2010     case PROP_ENDNOTE:
2011         result = "ENDNOTE";
2012 
2013         break;
2014     case PROP_FOOTNOTE:
2015         result = "FOOTNOTE";
2016 
2017         break;
2018     case PROP_ANNOTATION:
2019         result = "ANNOTATION";
2020 
2021         break;
2022     case PROP_DOC:
2023         result = "DOC";
2024 
2025         break;
2026 
2027     case PROP_SEC:
2028         result = "SEC";
2029 
2030         break;
2031 
2032     case PROP_PAP:
2033         result = "PAP";
2034 
2035         break;
2036 
2037     case PROP_CHP:
2038         result = "CHP";
2039 
2040         break;
2041     default:
2042         break;
2043     }
2044 
2045     return result;
2046 }
2047 
toString() const2048 string CpAndFc::toString() const
2049 {
2050     string result;
2051 
2052     result += "(";
2053     result += getCp().toString();
2054     result += ", ";
2055     result += getFc().toString();
2056     result += ", ";
2057 
2058     result += propertyTypeToString(getType());
2059 
2060     result += ")";
2061 
2062     return result;
2063 }
2064 
2065 
2066 // Bookmark
2067 
Bookmark(writerfilter::Reference<Properties>::Pointer_t pBKF,rtl::OUString & rName)2068 Bookmark::Bookmark(writerfilter::Reference<Properties>::Pointer_t pBKF,
2069                    rtl::OUString & rName)
2070 : mpBKF(pBKF), mName(rName)
2071 {
2072 }
2073 
resolve(Properties & rHandler)2074 void Bookmark::resolve(Properties & rHandler)
2075 {
2076     mpBKF->resolve(rHandler);
2077 
2078     WW8Value::Pointer_t pValue = createValue(mName);
2079     rHandler.attribute(NS_rtf::LN_BOOKMARKNAME, *pValue);
2080 }
2081 
getType() const2082 string Bookmark::getType() const
2083 {
2084     return "Bookmark";
2085 }
2086 
2087 // BookmarkHelper
2088 
getStartCpAndFc(sal_uInt32 nPos)2089 CpAndFc BookmarkHelper::getStartCpAndFc(sal_uInt32 nPos)
2090 {
2091     Cp aCp(mpStartCps->getFc(nPos));
2092     Fc aFc(mpPieceTable->cp2fc(aCp));
2093     CpAndFc aCpAndFc(aCp, aFc, PROP_BOOKMARKSTART);
2094 
2095     return aCpAndFc;
2096 }
2097 
getEndCpAndFc(sal_uInt32 nPos)2098 CpAndFc BookmarkHelper::getEndCpAndFc(sal_uInt32 nPos)
2099 {
2100     Cp aCp(mpEndCps->getU32(nPos * 4));
2101     Fc aFc(mpPieceTable->cp2fc(aCp));
2102     CpAndFc aCpAndFc(aCp, aFc, PROP_BOOKMARKEND);
2103 
2104     return aCpAndFc;
2105 }
2106 
getName(sal_uInt32 nPos)2107 rtl::OUString BookmarkHelper::getName(sal_uInt32 nPos)
2108 {
2109     return mpNames->getEntry(nPos);
2110 }
2111 
getIndex(const CpAndFc & rCpAndFc)2112 sal_uInt32 BookmarkHelper::getIndex(const CpAndFc & rCpAndFc)
2113 {
2114     sal_uInt32 nResult = mpStartCps->getEntryCount();
2115 
2116     sal_uInt32 nCp = rCpAndFc.getCp().get();
2117 
2118     sal_uInt32 n;
2119     switch (rCpAndFc.getType())
2120     {
2121     case PROP_BOOKMARKSTART:
2122         {
2123             sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
2124 
2125             for (n = 0; n < nStartsCount; ++n)
2126             {
2127                 if (nCp == mpStartCps->getFc(n))
2128                 {
2129                     nResult = n;
2130 
2131                     break;
2132                 }
2133             }
2134 
2135             if (n == nStartsCount)
2136                 throw ExceptionNotFound("BookmarkHelper::getIndex");
2137         }
2138 
2139         break;
2140 
2141     case PROP_BOOKMARKEND:
2142         {
2143             sal_uInt32 nEndsCount = mpEndCps->getCount() / 4;
2144             sal_uInt32 nIndex = nEndsCount;
2145 
2146             for (n = 0; n < nEndsCount; ++n)
2147             {
2148                 if (nCp == mpEndCps->getU16(n * 4))
2149                 {
2150                     nIndex = n;
2151 
2152                     break;
2153                 }
2154             }
2155 
2156             if (n == nEndsCount)
2157                 throw ExceptionNotFound("BookmarkHelper::getIndex");
2158 
2159             {
2160                 {
2161                     sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
2162                     for (n = 0; n < nStartsCount; ++n)
2163                     {
2164                         WW8BKF::Pointer_t pBKF(mpStartCps->getEntry(n));
2165 
2166                         if (pBKF->get_ibkl() ==
2167                             sal::static_int_cast<sal_Int32>(nIndex))
2168                         {
2169                             nResult = n;
2170 
2171                             break;
2172                         }
2173                     }
2174 
2175                     if (n == nStartsCount)
2176                         throw ExceptionNotFound("BookmarkHelper::getIndex");
2177                 }
2178             }
2179         }
2180 
2181         break;
2182     default:
2183         break;
2184     }
2185 
2186     return nResult;
2187 }
2188 
init()2189 void BookmarkHelper::init()
2190 {
2191     {
2192         sal_uInt32 nStartsCount = mpStartCps->getEntryCount();
2193 
2194         for (sal_uInt32 n = 0; n < nStartsCount; ++n)
2195             mpDoc->insertCpAndFc(getStartCpAndFc(n));
2196     }
2197 
2198     {
2199         sal_uInt32 nEndsCount = mpEndCps->getCount() / 4;
2200 
2201         for (sal_uInt32 n = 0; n < nEndsCount; ++n)
2202             mpDoc->insertCpAndFc(getEndCpAndFc(n));
2203     }
2204 }
2205 
2206 writerfilter::Reference<Properties>::Pointer_t
getBKF(const CpAndFc & rCpAndFc)2207 BookmarkHelper::getBKF(const CpAndFc & rCpAndFc)
2208 {
2209     sal_uInt32 nIndex = getIndex(rCpAndFc);
2210 
2211     return writerfilter::Reference<Properties>::Pointer_t
2212         (mpStartCps->getEntryPointer(nIndex));
2213 }
2214 
2215 writerfilter::Reference<Properties>::Pointer_t
getBookmark(const CpAndFc & rCpAndFc)2216 BookmarkHelper::getBookmark(const CpAndFc & rCpAndFc)
2217 {
2218     writerfilter::Reference<Properties>::Pointer_t pResult;
2219 
2220     try
2221     {
2222         rtl::OUString aName = getName(rCpAndFc);
2223 
2224         pResult = writerfilter::Reference<Properties>::Pointer_t
2225             (new Bookmark(getBKF(rCpAndFc), aName));
2226     }
2227     catch (ExceptionNotFound e)
2228     {
2229         clog << e.getText() << endl;
2230     }
2231 
2232     return pResult;
2233 }
2234 
getName(const CpAndFc & rCpAndFc)2235 rtl::OUString BookmarkHelper::getName(const CpAndFc & rCpAndFc)
2236 {
2237     rtl::OUString sResult;
2238 
2239     sal_uInt32 nIndex = getIndex(rCpAndFc);
2240 
2241     sResult = getName(nIndex);
2242 
2243     return sResult;
2244 }
2245 
2246 template <class T, class Helper>
2247 struct ProcessPLCF2Map
2248 {
processwriterfilter::doctok::ProcessPLCF2Map2249     void process(typename PLCF<T>::Pointer_t pPlcf,
2250                  typename Helper::Map_t & rMap,
2251                  PropertyType type,
2252                  WW8DocumentImpl * pDoc)
2253     {
2254         if (pPlcf.get() != NULL)
2255         {
2256             sal_uInt32 nCount = pPlcf->getEntryCount();
2257 
2258             for (sal_uInt32 n = 0; n < nCount; n++)
2259             {
2260                 Cp aCp(pPlcf->getFc(n));
2261                 CpAndFc aCpAndFc(pDoc->getCpAndFc(aCp, type));
2262                 typename T::Pointer_t pT = pPlcf->getEntry(n);
2263 
2264                 rMap[aCpAndFc] = pT;
2265             }
2266         }
2267     }
2268 };
2269 
FieldHelper(PLCF<WW8FLD>::Pointer_t pPlcffldMom,WW8DocumentImpl * pDoc)2270 FieldHelper::FieldHelper(PLCF<WW8FLD>::Pointer_t pPlcffldMom,
2271                          WW8DocumentImpl * pDoc)
2272 : mpDoc(pDoc)
2273 {
2274     ProcessPLCF2Map<WW8FLD, FieldHelper> process;
2275     process.process(pPlcffldMom, mMap, PROP_FLD, pDoc);
2276 }
2277 
init()2278 void FieldHelper::init()
2279 {
2280     Map_t::iterator aIt;
2281 
2282     for (aIt = mMap.begin(); aIt != mMap.end(); aIt++)
2283     {
2284         mpDoc->insertCpAndFc(aIt->first);
2285     }
2286 }
2287 
getWW8FLD(const CpAndFc & rCpAndFc)2288 WW8FLD::Pointer_t FieldHelper::getWW8FLD(const CpAndFc & rCpAndFc)
2289 {
2290     WW8FLD::Pointer_t pFld = mMap[rCpAndFc];
2291 
2292     return pFld;
2293 }
2294 
2295 writerfilter::Reference<Properties>::Pointer_t
getField(const CpAndFc & rCpAndFc)2296 FieldHelper::getField(const CpAndFc & rCpAndFc)
2297 {
2298     WW8FLD::Pointer_t pFLD = getWW8FLD(rCpAndFc);
2299 
2300     return writerfilter::Reference<Properties>::Pointer_t
2301         (new WW8FLD(*pFLD));
2302 }
2303 
ShapeHelper(PLCF<WW8FSPA>::Pointer_t pPlcspaMom,PLCF<WW8FSPA>::Pointer_t pPlcspaHdr,WW8DocumentImpl * pDoc)2304 ShapeHelper::ShapeHelper(PLCF<WW8FSPA>::Pointer_t pPlcspaMom,
2305                          PLCF<WW8FSPA>::Pointer_t pPlcspaHdr,
2306                          WW8DocumentImpl * pDoc)
2307 : mpDoc(pDoc)
2308 {
2309     ProcessPLCF2Map<WW8FSPA, ShapeHelper> process;
2310     process.process(pPlcspaMom, mMap, PROP_SHP, pDoc);
2311     process.process(pPlcspaHdr, mMap, PROP_SHP, pDoc);
2312 }
2313 
init()2314 void ShapeHelper::init()
2315 {
2316     Map_t::iterator aIt;
2317 
2318     for (aIt = mMap.begin(); aIt != mMap.end(); aIt++)
2319     {
2320         mpDoc->insertCpAndFc(aIt->first);
2321         aIt->second->setDocument(mpDoc);
2322     }
2323 }
2324 
2325 writerfilter::Reference<Properties>::Pointer_t
getShape(const CpAndFc & rCpAndFc)2326 ShapeHelper::getShape(const CpAndFc & rCpAndFc)
2327 {
2328     WW8FSPA::Pointer_t pFSPA = mMap[rCpAndFc];
2329 
2330     return writerfilter::Reference<Properties>::Pointer_t
2331         (new WW8FSPA(*pFSPA));
2332 }
2333 
BreakHelper(PLCF<WW8BKD>::Pointer_t pPlcfbkdMom,WW8DocumentImpl * pDoc)2334 BreakHelper::BreakHelper(PLCF<WW8BKD>::Pointer_t pPlcfbkdMom,
2335                          WW8DocumentImpl * pDoc)
2336 : mpDoc(pDoc)
2337 {
2338     ProcessPLCF2Map<WW8BKD, BreakHelper> process;
2339     process.process(pPlcfbkdMom, mMap, PROP_BRK, pDoc);
2340 }
2341 
init()2342 void BreakHelper::init()
2343 {
2344     Map_t::iterator aIt;
2345 
2346     for (aIt = mMap.begin(); aIt != mMap.end(); aIt++)
2347     {
2348         mpDoc->insertCpAndFc(aIt->first);
2349     }
2350 }
2351 
2352 writerfilter::Reference<Properties>::Pointer_t
getBreak(const CpAndFc & rCpAndFc)2353 BreakHelper::getBreak(const CpAndFc & rCpAndFc)
2354 {
2355     WW8BKD::Pointer_t pBKD = mMap[rCpAndFc];
2356 
2357     return writerfilter::Reference<Properties>::Pointer_t
2358         (new WW8BKD(*pBKD));
2359 }
2360 
2361 
2362 }}
2363