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