update dev300-m58
[ooovba.git] / sw / source / filter / ww1 / w1class.cxx
blob7fb33d4529dfe5af87686c24587c711ae51083fe
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: w1class.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <string.h>
36 #include <tools/stream.hxx>
38 #ifndef _W1CLASS_HXX
39 #include <w1class.hxx>
40 #endif
43 #ifdef DUMP
44 static const sal_Char* pUnknown = "?";
45 #define DUMPNAME(s) s
46 #else
47 #define DUMPNAME(s) 0
48 #endif
50 Ww1SingleSprm* Ww1Sprm::aTab[ 256 ];
51 Ww1SingleSprm* Ww1Sprm::pSingleSprm = 0;
55 /////////////////////////////////////////////////////////////////// Fib
56 Ww1Fib::Ww1Fib( SvStream& _rStream )
57 : rStream(_rStream)
59 bOK = 0 == rStream.Seek(0) &&
60 rStream.Read( &aFib, sizeof( aFib )) == sizeof( aFib );
63 ///////////////////////////////////////////////////////////// PlainText
65 Ww1PlainText::Ww1PlainText(Ww1Fib& rWwFib, ULONG nFilePos, ULONG nCountBytes)
66 : rFib(rWwFib), ulFilePos(nFilePos), ulCountBytes(nCountBytes),
67 ulSeek(0), bOK(true)
71 sal_Unicode Ww1PlainText::operator [] ( ULONG ulOffset )
73 DBG_ASSERT( ulOffset<Count(), "Ww1PlainText" );
74 sal_Unicode cRet;
75 sal_Char cRead;
76 if( rFib.GetStream().Seek( ulFilePos + ulOffset ) == ulFilePos+ulOffset &&
77 rFib.GetStream().Read( &cRead, sizeof( cRead ) ) == sizeof( cRead ) )
79 cRet = ByteString::ConvertToUnicode( cRead, RTL_TEXTENCODING_MS_1252 );
81 else
82 cRet = ' ';
83 return cRet;
86 String Ww1PlainText::GetText( ULONG ulOffset, ULONG nLen ) const
88 String sRet;
89 ByteString aStr;
90 DBG_ASSERT(ulOffset+nLen<Count(), "Ww1PlainText");
91 if( rFib.GetStream().Seek(ulFilePos+ulOffset) == ulFilePos+ulOffset &&
92 rFib.GetStream().Read( aStr.AllocBuffer( static_cast< xub_StrLen >(nLen) ), nLen ) == nLen )
93 sRet = String( aStr, RTL_TEXTENCODING_MS_1252 );
94 return sRet;
97 ///////////////////////////////////////////////////////////////// Style
98 Ww1Style::Ww1Style()
99 : pPapx(0), pParent(0), stcBase(0), stcNext(0), bUsed(false)
103 Ww1Style::~Ww1Style()
105 delete pPapx;
108 void Ww1Style::SetDefaults(BYTE stc)
110 if( 222 == stc )
112 stcBase = 222;
113 stcNext = 222;
114 aChpx.hpsSet(20);
118 USHORT Ww1Style::ReadName( BYTE*&p, USHORT& rnCountBytes, USHORT stc )
120 BYTE nCountBytes = SVBT8ToByte(p);
121 p++;
122 rnCountBytes--;
123 if( !nCountBytes ) // default
125 static const sal_Char* __READONLY_DATA names[] =
127 "W1 Null", //222
128 "W1 Annotation reference", //223
129 "W1 Annotation text", //224
130 "W1 Table of contents 8", //225
131 "W1 Table of contents 7", //226
132 "W1 Table of contents 6", //227
133 "W1 Table of contents 5", //228
134 "W1 Table of contents 4", //229
135 "W1 Table of contents 3", //230
136 "W1 Table of contents 2", //231
137 "W1 Table of contents 1", //232
138 "W1 Index 7", //233
139 "W1 Index 6", //234
140 "W1 Index 5", //235
141 "W1 Index 4", //236
142 "W1 Index 3", //237
143 "W1 Index 2", //238
144 "W1 Index 1", //239
145 "W1 Line number", //240
146 "W1 Index heading", //241
147 "W1 Footer", //242
148 "W1 Header", //243
149 "W1 Footnote reference", //244
150 "W1 Footnote text", //245
151 "W1 Heading 9", //246
152 "W1 Heading 8", //247
153 "W1 Heading 7", //248
154 "W1 Heading 6", //249
155 "W1 Heading 5", //250
156 "W1 Heading 4", //251
157 "W1 Heading 3", //252
158 "W1 Heading 2", //253
159 "W1 Heading 1", //254
160 "W1 Normal indent" //255
161 };//256
163 const sal_Char* pStr;
164 size_t nSize(stc);
165 if (!nSize)
166 pStr = "W1 Normal";
167 else if (nSize - 222 >= sizeof(names) / sizeof(*names))
168 pStr = "?";
169 else
170 pStr = names[nSize-222];
171 SetName(String(pStr, RTL_TEXTENCODING_MS_1252));
173 else if( 255 > nCountBytes ) // unused
175 SetName( String( (sal_Char*)p, nCountBytes, RTL_TEXTENCODING_MS_1252 ));
176 p += nCountBytes;
177 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style");
178 rnCountBytes = rnCountBytes - nCountBytes;
180 return 0;
183 USHORT Ww1Style::ReadChpx( BYTE*&p, USHORT& rnCountBytes )
185 USHORT nCountBytes = SVBT8ToByte(p);
186 p++;
187 rnCountBytes--;
188 if (nCountBytes != 255 // unused
189 && nCountBytes != 0) // default
191 if (nCountBytes > sizeof(aChpx))
192 nCountBytes = sizeof(aChpx);
193 memcpy( &aChpx, p, nCountBytes );
194 p += nCountBytes;
195 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style");
196 rnCountBytes = rnCountBytes - nCountBytes;
198 return 0;
201 USHORT Ww1Style::ReadPapx(BYTE*&p, USHORT& rnCountBytes)
203 USHORT nCountBytes = SVBT8ToByte(p);
204 p++;
205 rnCountBytes--;
206 if (nCountBytes != 255)
208 pPapx = new Ww1SprmPapx(p, nCountBytes);
209 p += nCountBytes;
210 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1Style");
211 rnCountBytes = rnCountBytes - nCountBytes;
213 else
214 pPapx = new Ww1SprmPapx(p, 0);
215 return 0;
218 USHORT Ww1Style::ReadEstcp(BYTE*&p, USHORT& rnCountBytes)
220 stcNext = SVBT8ToByte(p);
221 p++;
222 rnCountBytes--;
223 stcBase = SVBT8ToByte(p);
224 p++;
225 DBG_ASSERT(rnCountBytes>0, "Ww1Style");
226 rnCountBytes--;
227 return 0;
230 //////////////////////////////////////////////////////////// StyleSheet
231 Ww1StyleSheet::Ww1StyleSheet(Ww1Fib& _rFib)
232 : cstcStd(0),
233 rFib(_rFib),
234 bOK(FALSE)
236 USHORT cbStshf = rFib.GetFIB().cbStshfGet();
237 DBG_ASSERT(cbStshf>=17, "Ww1StyleSheet");
238 for (USHORT stc=0;stc<Count();stc++)
240 aStyles[stc].SetParent(this);
241 aStyles[stc].SetDefaults((BYTE)stc);
243 BYTE* del = NULL;
244 if (rFib.GetStream().Seek(rFib.GetFIB().fcStshfGet())
245 == (ULONG)rFib.GetFIB().fcStshfGet()
246 && (del = new BYTE[cbStshf]) != NULL
247 && rFib.GetStream().Read(del, cbStshf) == (ULONG)cbStshf)
249 BYTE* p = del;
250 cstcStd = SVBT16ToShort(p);
251 p += sizeof(SVBT16);
252 cbStshf -= sizeof(SVBT16);
253 ReadNames(p, cbStshf);
254 ReadChpx(p, cbStshf);
255 ReadPapx(p, cbStshf);
256 ReadEstcp(p, cbStshf);
257 DBG_ASSERT(cbStshf==0, "Ww1StyleSheet");
258 bOK = cbStshf == 0;
260 delete del;
263 USHORT Ww1StyleSheet::ReadNames( BYTE*& p, USHORT& rnCountBytes )
265 USHORT nCountBytes = SVBT16ToShort(p);
266 p += sizeof(SVBT16);
267 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
268 rnCountBytes = rnCountBytes - nCountBytes;
269 nCountBytes = nCountBytes - sizeof(SVBT16);
270 USHORT stcp = 0;
271 while (nCountBytes > 0)
273 USHORT stc = (stcp - cstcStd) & 255;
274 aStyles[stc].ReadName(p, nCountBytes, stc);
275 stcp++;
277 DBG_ASSERT(nCountBytes==0, "Ww1StyleSheet");
278 return 0;
281 USHORT Ww1StyleSheet::ReadChpx(BYTE*& p, USHORT& rnCountBytes)
283 USHORT nCountBytes = SVBT16ToShort(p);
284 p += sizeof(SVBT16);
285 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
286 rnCountBytes = rnCountBytes - nCountBytes;
287 nCountBytes = nCountBytes - sizeof(SVBT16);
288 USHORT stcp = 0;
289 while (nCountBytes > 0)
291 USHORT stc = (stcp - cstcStd) & 255;
292 aStyles[stc].ReadChpx(p, nCountBytes);
293 stcp++;
295 DBG_ASSERT(nCountBytes == 0, "Ww1StyleSheet");
296 return 0;
299 USHORT Ww1StyleSheet::ReadPapx(BYTE*& p, USHORT& rnCountBytes)
301 USHORT nCountBytes = SVBT16ToShort(p);
302 p += sizeof(SVBT16);
303 DBG_ASSERT(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
304 rnCountBytes = rnCountBytes - nCountBytes;
305 nCountBytes = nCountBytes - sizeof(SVBT16);
306 USHORT stcp = 0;
307 while (nCountBytes > 0)
309 USHORT stc = (stcp - cstcStd) & 255;
310 aStyles[stc].ReadPapx(p, nCountBytes);
311 stcp++;
313 DBG_ASSERT(nCountBytes == 0, "Ww1StyleSheet");
314 return 0;
317 USHORT Ww1StyleSheet::ReadEstcp(BYTE*& p, USHORT& rnCountBytes)
319 USHORT iMac = SVBT16ToShort(p);
320 p += sizeof(SVBT16);
321 DBG_ASSERT(rnCountBytes>=sizeof(SVBT16), "Ww1StyleSheet");
322 rnCountBytes -= sizeof(SVBT16);
323 for (USHORT stcp=0;stcp<iMac;stcp++)
325 USHORT stc = (stcp - cstcStd) & 255;
326 aStyles[stc].ReadEstcp(p, rnCountBytes);
328 DBG_ASSERT(rnCountBytes==0, "Ww1StyleSheet");
329 return 0;
332 ///////////////////////////////////////////////////////////////// Fonts
334 Ww1Fonts::Ww1Fonts(Ww1Fib& rInFib, ULONG nFieldFlgs)
335 : pFontA(0), rFib(rInFib), nFieldFlags(nFieldFlgs), nMax(0), bOK(false)
337 if(rFib.GetFIB().cbSttbfffnGet() > 2 ) // ueberhaupt fonts?
339 SVBT16 nCountBytes;
340 DBG_ASSERT(rFib.GetFIB().cbSttbfffnGet() > sizeof(nCountBytes), "Ww1Fonts");
341 if (rFib.GetStream().Seek(rFib.GetFIB().fcSttbfffnGet())
342 == (ULONG)rFib.GetFIB().fcSttbfffnGet())
343 if (rFib.GetStream().Read(nCountBytes, sizeof(nCountBytes))
344 == sizeof(nCountBytes)) // Laenge steht hier nochmal
346 DBG_ASSERT(SVBT16ToShort(nCountBytes)
347 == rFib.GetFIB().cbSttbfffnGet(), "redundant-size missmatch");
348 // hoffentlich sind sie immer gleich
349 W1_FFN* pA = (W1_FFN*)new char[rFib.GetFIB().cbSttbfffnGet()
350 - sizeof(nCountBytes)]; // Alloziere Font-Array
351 //~ Ww1: new-NULL
352 if (rFib.GetStream().Read(pA, rFib.GetFIB().cbSttbfffnGet()
353 - sizeof(nCountBytes)) == (ULONG)rFib.GetFIB().cbSttbfffnGet()
354 - sizeof(nCountBytes)) // lese alle Fonts
355 {} //nothing
357 long nLeft = rFib.GetFIB().cbSttbfffnGet()
358 - sizeof(nCountBytes); // Zaehle, wieviele Fonts enthalten
359 W1_FFN* p = pA;
360 while (1)
362 USHORT nNextSiz;
363 nNextSiz = p->cbFfnM1Get() + 1;
364 if(nNextSiz > nLeft)
365 break;
366 nMax++;
367 nLeft -= nNextSiz;
368 if(nLeft < 1) // naechste Laenge muss gelesen werden koennen
369 break;
370 p = (W1_FFN *)(((char*)p) + nNextSiz);
372 if (nMax)
374 pFontA = new W1_FFN*[nMax]; // alloziere Index-Array
375 //~ Ww1: new-NULL
376 pFontA[0] = pA; // fuelle Index-Array
377 USHORT i;
378 for(i=1, p=pA; i<nMax; i++)
380 p = (W1_FFN*)(((char*)p) + p->cbFfnM1Get() + 1);
381 pFontA[i] = p;
384 else
385 pFontA = 0; // Keine Eintraege -> kein Array
388 bOK = TRUE;
391 W1_FFN* Ww1Fonts::GetFFN(USHORT nNum)
393 W1_FFN* pRet = NULL;
394 if (pFontA)
395 if (nNum < nMax)
396 pRet = pFontA[nNum];
397 return pRet;
400 /////////////////////////////////////////////////////////////////// DOP
401 Ww1Dop::Ww1Dop(Ww1Fib& _rFib)
402 : rFib(_rFib)
404 long nRead;
405 memset(&aDop, 0, sizeof(aDop)); // set defaults
406 if(rFib.GetFIB().cbDopGet() >= sizeof(aDop))
407 nRead = sizeof(aDop);
408 else
409 nRead = rFib.GetFIB().cbDopGet();
410 bOK = rFib.GetStream().Seek(rFib.GetFIB().fcDopGet()) ==
411 (ULONG)rFib.GetFIB().fcDopGet() &&
412 rFib.GetStream().Read(&aDop, nRead) == (ULONG)nRead;
415 /////////////////////////////////////////////////////////////// Picture
416 Ww1Picture::Ww1Picture(SvStream& rStream, ULONG ulFilePos)
417 : bOK(false), pPic(0)
419 ulFilePos &= 0xffffff; //~ ww1: warum auch immer - im highbyte steht eine 5?!?!
420 SVBT32 lcb;
421 if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos)
422 if (rStream.Read(&lcb, sizeof(lcb)) == (ULONG)sizeof(lcb))
423 if (sizeof(int)>=4 || SVBT32ToUInt32(lcb) < 0x8000) //~ mdt: 64K & 16bit
424 if ((pPic = (W1_PIC*)(new BYTE[SVBT32ToUInt32(lcb)])) != NULL)
425 if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos)
426 if (rStream.Read(pPic, SVBT32ToUInt32(lcb)) == (ULONG)SVBT32ToUInt32(lcb))
428 DBG_ASSERT(pPic->cbHeaderGet()==sizeof(*pPic)-sizeof(pPic->rgb), "Ww1Picture");
429 bOK = true;
433 ////////////////////////////////////////////////////////////////// Sprm
434 Ww1Sprm::Ww1Sprm(BYTE* x, USHORT _nCountBytes)
435 : p(NULL),
436 nCountBytes(_nCountBytes),
437 bOK(FALSE),
438 pArr(NULL),
439 count(0)
441 if (nCountBytes == 0)
442 bOK = TRUE;
443 else
444 if ((p = new BYTE[nCountBytes]) != NULL)
446 memcpy(p, x, nCountBytes);
447 if (ReCalc())
448 bOK = TRUE;
452 Ww1Sprm::Ww1Sprm(SvStream& rStream, ULONG ulFilePos)
453 : p(NULL),
454 nCountBytes(0),
455 bOK(FALSE),
456 pArr(NULL),
457 count(0)
459 SVBT8 x;
460 ByteToSVBT8(0, x);
461 if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos)
462 if (rStream.Read(&x, sizeof(x)) == (ULONG)sizeof(x))
463 if ((nCountBytes = SVBT8ToByte(x)) == 255
464 || !nCountBytes
465 || (p = new BYTE[nCountBytes]) != NULL)
466 if (nCountBytes == 255
467 || !nCountBytes
468 || rStream.Read(p, nCountBytes) == (ULONG)nCountBytes)
469 if (ReCalc())
470 bOK = TRUE;
473 Ww1Sprm::~Ww1Sprm()
475 delete pArr;
476 delete p;
479 USHORT Ww1SingleSprm::Size(BYTE* /*pSprm*/)
481 return nCountBytes;
484 USHORT Ww1SingleSprmTab::Size(BYTE* pSprm) // Doc 24/25, Fastsave-Sprm
486 DBG_ASSERT(nCountBytes==0, "Ww1SingleSprmTab");
487 USHORT nRet = sizeof(SVBT8);
488 USHORT nSize = SVBT8ToByte(pSprm);
489 if (nSize != 255)
490 nRet = nRet + nSize;
491 else
493 USHORT nDel = SVBT8ToByte(pSprm+1) * 4;
494 USHORT nIns = SVBT8ToByte(pSprm + 3 + nDel) * 3;
495 nRet += nDel + nIns;
497 DBG_ASSERT(nRet <= 354, "Ww1SingleSprmTab");
498 if (nRet > 354)
499 nRet = 0;
500 return nRet;
503 USHORT Ww1SingleSprmByteSized::Size(BYTE* pSprm)
505 USHORT nRet;
506 nRet = SVBT8ToByte(pSprm);
507 nRet += sizeof(SVBT8); // var. l. byte-size
508 // pSprm += sizeof(SVBT8); // var. l. byte-size
509 nRet = nRet + nCountBytes;
510 return nRet;
513 USHORT Ww1SingleSprmWordSized::Size(BYTE* pSprm)
515 USHORT nRet;
516 nRet = SVBT16ToShort(pSprm);
517 nRet += sizeof(SVBT16); // var. l. word-size
518 // pSprm += sizeof(SVBT16); // var. l. word-size
519 nRet = nRet + nCountBytes;
520 return nRet;
523 static BYTE nLast = 0;
524 static BYTE nCurrent = 0;
525 USHORT Ww1Sprm::GetSize(BYTE nId, BYTE* pSprm)
527 //DBG_ASSERT( nId < sizeof(aTab) / sizeof(*aTab), "Ww1Sprm" );
528 USHORT nL = 0;
529 nL = GetTab(nId).Size(pSprm);
530 nLast = nCurrent;
531 nCurrent = nId;
532 return nL;
535 BOOL Ww1Sprm::Fill(USHORT index, BYTE& nId, USHORT& nL, BYTE*& pSprm)
537 //DBG_ASSERT( nId < sizeof(aTab) / sizeof(*aTab), "Ww1Sprm");
538 DBG_ASSERT(index < Count(), "Ww1Sprm");
539 pSprm = p + pArr[index];
540 nId = SVBT8ToByte(pSprm);
541 pSprm++;
542 nL = GetTab(nId).Size(pSprm);
543 return TRUE;
546 BOOL Ww1Sprm::ReCalc()
548 BOOL bRet = TRUE;
549 delete pArr;
550 pArr = NULL;
551 count = 0;
552 if (nCountBytes != 255) // not unused?
554 USHORT cbsik = nCountBytes;
555 BYTE* psik = p;
556 while (cbsik > 0)
558 USHORT iLen = GetSizeBrutto(psik);
559 DBG_ASSERT(iLen<=cbsik, "Ww1Sprm");
560 if (iLen > cbsik)
561 cbsik = 0; // ignore the rest: we are wrong...
562 else
564 psik += iLen;
565 cbsik = cbsik - iLen;
566 count++;
569 if (bRet
570 && (pArr = new USHORT[count]) != NULL)
572 cbsik = nCountBytes;
573 USHORT offset = 0;
574 USHORT current = 0;
575 psik = p;
576 while (current<count)
578 pArr[current++] = offset;
579 USHORT iLen = GetSizeBrutto(psik);
580 psik += iLen;
581 if (iLen > cbsik)
582 cbsik = 0;
583 else
584 cbsik = cbsik - iLen;
585 offset = offset + iLen;
589 else
590 count = 0;
592 return bRet;
595 void Ww1Sprm::DeinitTab()
597 for (size_t i=0; i < sizeof(aTab)/sizeof(*aTab); ++i)
598 delete aTab[i];
599 memset(aTab, 0, sizeof(aTab)/sizeof(*aTab));
600 delete pSingleSprm;
603 void Ww1Sprm::InitTab()
605 memset(aTab, 0, sizeof(aTab)/sizeof(*aTab));
606 pSingleSprm = new Ww1SingleSprm( 0, DUMPNAME(pUnknown));
608 aTab[ 2] = new Ww1SingleSprmByte(DUMPNAME("sprmPStc")); // 2 pap.istd (style code)
609 aTab[ 3] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPIstdPermute")); // 3 pap.istd permutation
610 aTab[ 4] = new Ww1SingleSprmByte(DUMPNAME("sprmPIncLevel")); // 4 pap.istddifference
611 aTab[ 5] = new Ww1SingleSprmPJc(DUMPNAME("sprmPJc")); // 5 pap.jc (justification)
612 aTab[ 6] = new Ww1SingleSprmBool(DUMPNAME("sprmPFSideBySide")); // 6 pap.fSideBySide
613 aTab[ 7] = new Ww1SingleSprmPFKeep(DUMPNAME("sprmPFKeep")); // 7 pap.fKeep
614 aTab[ 8] = new Ww1SingleSprmPFKeepFollow(DUMPNAME("sprmPFKeepFollow")); // 8 pap.fKeepFollow
615 aTab[ 9] = new Ww1SingleSprmPPageBreakBefore(DUMPNAME("sprmPPageBreakBefore")); // 9 pap.fPageBreakBefore
616 aTab[ 10] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcl")); // 10 pap.brcl
617 aTab[ 11] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcp")); // 11 pap.brcp
618 aTab[ 12] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPAnld")); // 12 pap.anld (ANLD structure)
619 aTab[ 13] = new Ww1SingleSprmByte(DUMPNAME("sprmPNLvlAnm")); // 13 pap.nLvlAnm nn
620 aTab[ 14] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoLineNumb")); // 14 ap.fNoLnn
621 aTab[ 15] = new Ww1SingleSprmPChgTabsPapx(DUMPNAME("sprmPChgTabsPapx")); // 15 pap.itbdMac, ...
622 aTab[ 16] = new Ww1SingleSprmPDxaRight(DUMPNAME("sprmPDxaRight")); // 16 pap.dxaRight
623 aTab[ 17] = new Ww1SingleSprmPDxaLeft(DUMPNAME("sprmPDxaLeft")); // 17 pap.dxaLeft
624 aTab[ 18] = new Ww1SingleSprmWord(DUMPNAME("sprmPNest")); // 18 pap.dxaNest
625 aTab[ 19] = new Ww1SingleSprmPDxaLeft1(DUMPNAME("sprmPDxaLeft1")); // 19 pap.dxaLeft1
626 aTab[ 20] = new Ww1SingleSprmPDyaLine(DUMPNAME("sprmPDyaLine")); // 20 pap.lspd an LSPD
627 aTab[ 21] = new Ww1SingleSprmPDyaBefore(DUMPNAME("sprmPDyaBefore")); // 21 pap.dyaBefore
628 aTab[ 22] = new Ww1SingleSprmPDyaAfter(DUMPNAME("sprmPDyaAfter")); // 22 pap.dyaAfter
629 aTab[ 23] = new Ww1SingleSprmTab(0, DUMPNAME(pUnknown)); // 23 pap.itbdMac, pap.rgdxaTab
630 aTab[ 24] = new Ww1SingleSprmPFInTable(DUMPNAME("sprmPFInTable")); // 24 pap.fInTable
631 aTab[ 25] = new Ww1SingleSprmPTtp(DUMPNAME("sprmPTtp")); // 25 pap.fTtp
632 aTab[ 26] = new Ww1SingleSprmPDxaAbs(DUMPNAME("sprmPDxaAbs")); // 26 pap.dxaAbs
633 aTab[ 27] = new Ww1SingleSprmPDyaAbs(DUMPNAME("sprmPDyaAbs")); // 27 pap.dyaAbs
634 aTab[ 28] = new Ww1SingleSprmPDxaWidth(DUMPNAME("sprmPDxaWidth")); // 28 pap.dxaWidth
635 aTab[ 29] = new Ww1SingleSprmPpc(DUMPNAME("sprmPPc")); // 29 pap.pcHorz, pap.pcVert
636 aTab[ 30] = new Ww1SingleSprmPBrc10(BRC_TOP, DUMPNAME("sprmPBrcTop10")); // 30 pap.brcTop BRC10
637 aTab[ 31] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcLeft10")); // 31 pap.brcLeft BRC10
638 aTab[ 32] = new Ww1SingleSprmPBrc10(BRC_BOTTOM, DUMPNAME("sprmPBrcBottom10")); // 32 pap.brcBottom BRC10
639 aTab[ 33] = new Ww1SingleSprmPBrc10(BRC_RIGHT, DUMPNAME("sprmPBrcRight10")); // 33 pap.brcRight BRC10
640 aTab[ 34] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween10")); // 34 pap.brcBetween BRC10
641 aTab[ 35] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcBar10")); // 35 pap.brcBar BRC10
642 aTab[ 36] = new Ww1SingleSprmPFromText(DUMPNAME("sprmPFromText10")); // 36 pap.dxaFromText dxa
643 aTab[ 37] = new Ww1SingleSprmByte(DUMPNAME("sprmPWr")); // 37 pap.wr wr
644 aTab[ 38] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcTop")); // 38 pap.brcTop BRC
645 aTab[ 39] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcLeft")); // 39 pap.brcLeft BRC
646 aTab[ 40] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBottom")); // 40 pap.brcBottom BRC
647 aTab[ 41] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcRight")); // 41 pap.brcRight BRC
648 aTab[ 42] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween")); // 42 pap.brcBetween BRC
649 aTab[ 43] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBar")); // 43 pap.brcBar BRC word
650 aTab[ 44] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoAutoHyph")); // 44 pap.fNoAutoHyph
651 aTab[ 45] = new Ww1SingleSprmWord(DUMPNAME("sprmPWHeightAbs")); // 45 pap.wHeightAbs w
652 aTab[ 46] = new Ww1SingleSprmWord(DUMPNAME("sprmPDcs")); // 46 pap.dcs DCS
653 aTab[ 47] = new Ww1SingleSprmWord(DUMPNAME("sprmPShd")); // 47 pap.shd SHD
654 aTab[ 48] = new Ww1SingleSprmWord(DUMPNAME("sprmPDyaFromText")); // 48 pap.dyaFromText dya
655 aTab[ 49] = new Ww1SingleSprmWord(DUMPNAME("sprmPDxaFromText")); // 49 pap.dxaFromText dxa
656 aTab[ 50] = new Ww1SingleSprmBool(DUMPNAME("sprmPFLocked")); // 50 pap.fLocked 0 or 1 byte
657 aTab[ 51] = new Ww1SingleSprmBool(DUMPNAME("sprmPFWidowControl")); // 51 pap.fWidowControl 0 or 1 byte
659 aTab[ 57] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmCDefault")); // 57 whole CHP (see below) none variable length
660 aTab[ 58] = new Ww1SingleSprm(0, DUMPNAME("sprmCPlain")); // 58 whole CHP (see below) none 0
662 aTab[ 60] = new Ww1SingleSprm4State(DUMPNAME("sprmCFBold")); // 60 chp.fBold 0,1, 128, or 129 (see below) byte
663 aTab[ 61] = new Ww1SingleSprm4State(DUMPNAME("sprmCFItalic")); // 61 chp.fItalic 0,1, 128, or 129 (see below) byte
664 aTab[ 62] = new Ww1SingleSprm4State(DUMPNAME("sprmCFStrike")); // 62 chp.fStrike 0,1, 128, or 129 (see below) byte
665 aTab[ 63] = new Ww1SingleSprm4State(DUMPNAME("sprmCFOutline")); // 63 chp.fOutline 0,1, 128, or 129 (see below) byte
666 aTab[ 64] = new Ww1SingleSprm4State(DUMPNAME("sprmCFShadow")); // 64 chp.fShadow 0,1, 128, or 129 (see below) byte
667 aTab[ 65] = new Ww1SingleSprm4State(DUMPNAME("sprmCFSmallCaps")); // 65 chp.fSmallCaps 0,1, 128, or 129 (see below) byte
668 aTab[ 66] = new Ww1SingleSprm4State(DUMPNAME("sprmCFCaps")); // 66 chp.fCaps 0,1, 128, or 129 (see below) byte
669 aTab[ 67] = new Ww1SingleSprm4State(DUMPNAME("sprmCFVanish")); // 67 chp.fVanish 0,1, 128, or 129 (see below) byte
670 aTab[ 68] = new Ww1SingleSprmWord(DUMPNAME("sprmCFtc")); // 68 chp.ftc ftc word
671 aTab[ 69] = new Ww1SingleSprmByte(DUMPNAME("sprmCKul")); // 69 chp.kul kul byte
672 aTab[ 70] = new Ww1SingleSprm(3, DUMPNAME("sprmCSizePos")); // 70 chp.hps, chp.hpsPos (see below) 3 bytes
673 aTab[ 71] = new Ww1SingleSprmWord(DUMPNAME("sprmCDxaSpace")); // 71 chp.dxaSpace dxa word
674 aTab[ 72] = new Ww1SingleSprmWord(DUMPNAME("//")); // 72 //
675 aTab[ 73] = new Ww1SingleSprmByte(DUMPNAME("sprmCIco")); // 73 chp.ico ico byte
676 aTab[ 74] = new Ww1SingleSprmByte(DUMPNAME("sprmCHps")); // 74 chp.hps hps !byte!
677 aTab[ 75] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsInc")); // 75 chp.hps (see below) byte
678 aTab[ 76] = new Ww1SingleSprmWord(DUMPNAME("sprmCHpsPos")); // 76 chp.hpsPos hps !word!
679 aTab[ 77] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsPosAdj")); // 77 chp.hpsPos hps (see below) byte
680 aTab[ 78] = new Ww1SingleSprmByteSized(0, DUMPNAME(pUnknown)); // 78 ?chp.fBold, chp.fItalic, chp.fSmallCaps, ...
682 aTab[ 94] = new Ww1SingleSprmByte(DUMPNAME("sprmPicBrcl")); // 94 pic.brcl brcl (see PIC structure definition) byte
683 aTab[ 95] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPicScale")); // 95 pic.mx, pic.my, pic.dxaCropleft,
685 aTab[117] = new Ww1SingleSprmByte(DUMPNAME("sprmSBkc")); // 117 sep.bkc bkc byte
686 aTab[118] = new Ww1SingleSprmBool(DUMPNAME("sprmSFTitlePage")); // 118 sep.fTitlePage 0 or 1 byte
687 aTab[119] = new Ww1SingleSprmSColumns(DUMPNAME("sprmSCcolumns")); // 119 sep.ccolM1 # of cols - 1 word
688 aTab[120] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaColumns")); // 120 sep.dxaColumns dxa word
690 aTab[122] = new Ww1SingleSprmByte(DUMPNAME("sprmSNfcPgn")); // 122 sep.nfcPgn nfc byte
692 aTab[125] = new Ww1SingleSprmBool(DUMPNAME("sprmSFPgnRestart")); // 125 sep.fPgnRestart 0 or 1 byte
693 aTab[126] = new Ww1SingleSprmBool(DUMPNAME("sprmSFEndnote")); // 126 sep.fEndnote 0 or 1 byte
694 aTab[127] = new Ww1SingleSprmByte(DUMPNAME("sprmSLnc")); // 127 sep.lnc lnc byte
695 aTab[128] = new Ww1SingleSprmSGprfIhdt(DUMPNAME("sprmSGprfIhdt")); // 128 sep.grpfIhdt grpfihdt (see Headers and Footers topic) byte
696 aTab[129] = new Ww1SingleSprmWord(DUMPNAME("sprmSNLnnMod")); // 129 sep.nLnnMod non-neg int. word
697 aTab[130] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaLnn")); // 130 sep.dxaLnn dxa word
698 aTab[131] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrTop")); // 131 sep.dyaHdrTop dya word
699 aTab[132] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrBottom")); // 132 sep.dyaHdrBottom dya word
700 aTab[133] = new Ww1SingleSprmBool(DUMPNAME("sprmSLBetween")); // 133 sep.fLBetween 0 or 1 byte
701 aTab[134] = new Ww1SingleSprmByte(DUMPNAME("sprmSVjc")); // 134 sep.vjc vjc byte
702 aTab[135] = new Ww1SingleSprmWord(DUMPNAME("sprmSLnnMin")); // 135 sep.lnnMin lnn word
703 aTab[136] = new Ww1SingleSprmWord(DUMPNAME("sprmSPgnStart")); // 136 sep.pgnStart pgn word
705 aTab[146] = new Ww1SingleSprmWord(DUMPNAME("sprmTJc")); // 146 tap.jc jc word (low order byte is significant)
706 aTab[147] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaLeft")); // 147 tap.rgdxaCenter (see below) dxa word
707 aTab[148] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaGapHalf")); // 148 tap.dxaGapHalf, tap.rgdxaCenter (see below) dxa word
709 aTab[152] = new Ww1SingleSprmTDefTable10(DUMPNAME("sprmTDefTable10")); // 152 tap.rgdxaCenter, tap.rgtc complex (see below) variable length
710 aTab[153] = new Ww1SingleSprmWord(DUMPNAME("sprmTDyaRowHeight")); // 153 tap.dyaRowHeight dya word
712 aTab[158] = new Ww1SingleSprm(4, DUMPNAME("sprmTInsert")); // 158 tap.rgdxaCenter,tap.rgtc complex (see below) 4 bytes
713 aTab[159] = new Ww1SingleSprmWord(DUMPNAME("sprmTDelete")); // 159 tap.rgdxaCenter, tap.rgtc complex (see below) word
714 aTab[160] = new Ww1SingleSprm(4, DUMPNAME("sprmTDxaCol")); // 160 tap.rgdxaCenter complex (see below) 4 bytes
715 aTab[161] = new Ww1SingleSprmWord(DUMPNAME("sprmTMerge")); // 161 tap.fFirstMerged, tap.fMerged complex (see below) word
716 aTab[162] = new Ww1SingleSprmWord(DUMPNAME("sprmTSplit")); // 162 tap.fFirstMerged, tap.fMerged complex (see below) word
717 aTab[163] = new Ww1SingleSprm(5, DUMPNAME("sprmTSetBrc10")); // 163 tap.rgtc[].rgbrc complex (see below) 5 bytes
720 ////////////////////////////////////////////////////////////// SprmPapx
721 Ww1SprmPapx::Ww1SprmPapx(BYTE* pByte, USHORT nSize) :
722 Ww1Sprm(Sprm(pByte, nSize), SprmSize(pByte, nSize))
724 memset(&aPapx, 0, sizeof(aPapx));
725 memcpy(&aPapx, pByte, nSize<sizeof(aPapx)?nSize:sizeof(aPapx));
728 USHORT Ww1SprmPapx::SprmSize(BYTE*, USHORT nSize)
730 USHORT nRet = 0;
731 if (nSize >= sizeof(W1_PAPX))
732 nRet = nSize - ( sizeof(W1_PAPX) - 1 ); // im W1_PAPX ist das
733 // 1. SprmByte enthalten
734 return nRet;
737 BYTE* Ww1SprmPapx::Sprm(BYTE* pByte, USHORT nSize)
739 BYTE* pRet = NULL;
740 if (nSize >= sizeof(W1_PAPX))
741 pRet = ((W1_PAPX*)(pByte))->grpprlGet();
742 return pRet;
745 /////////////////////////////////////////////////////////////////// Plc
746 Ww1Plc::Ww1Plc(Ww1Fib& rInFib, ULONG ulFilePos, USHORT nInCountBytes,
747 USHORT nInItemSize)
748 : p(0), nCountBytes(nInCountBytes), iMac(0), nItemSize(nInItemSize),
749 bOK(false), rFib(rInFib)
751 if (!nCountBytes)
752 bOK = true;
753 else
755 if (rFib.GetStream().Seek(ulFilePos) == (ULONG)ulFilePos)
757 if ((p = new BYTE[nCountBytes]) != NULL)
759 if (rFib.GetStream().Read(p, nCountBytes) == (ULONG)nCountBytes)
761 bOK = true;
762 iMac = (nCountBytes -
763 sizeof(SVBT32)) / (sizeof(SVBT32) + nItemSize);
764 DBG_ASSERT(iMac * ((USHORT)sizeof(ULONG) + nItemSize) +
765 (USHORT)sizeof(SVBT32) == nCountBytes, "Ww1Plc");
772 Ww1Plc::~Ww1Plc()
774 delete p;
777 void Ww1Plc::Seek(ULONG ulSeek, USHORT& nIndex)
779 if (iMac)
780 for (;nIndex <= iMac && Where(nIndex) < ulSeek;nIndex++)
784 ULONG Ww1Plc::Where(USHORT nIndex)
786 ULONG ulRet = 0xffffffff;
787 DBG_ASSERT(nIndex <= iMac, "index out of bounds");
788 if (iMac && nIndex <= iMac)
789 ulRet = SVBT32ToUInt32(p + sizeof(SVBT32) * nIndex);
790 return ulRet;
793 BYTE* Ww1Plc::GetData(USHORT nIndex)
795 BYTE* pRet = NULL;
796 DBG_ASSERT(nIndex < iMac, "index out of bounds");
797 if (nIndex < iMac)
798 pRet = p + (iMac + 1) * sizeof(SVBT32) +
799 nIndex * nItemSize; // Pointer auf Inhalts-Array
800 return pRet;
803 /////////////////////////////////////////////////////////////////// Sep
805 //////////////////////////////////////////////////////////////// PlcSep
807 //////////////////////////////////////////////////////////////// PlcPap
809 //////////////////////////////////////////////////////////////// PlcChp
811 //////////////////////////////////////////////////////////////// PlcFnr
813 ///////////////////////////////////////////////////////////// PlcFnText
815 ///////////////////////////////////////////////////////////// PlcFields
817 ///////////////////////////////////////////////////////////// PlcBookmarks
818 // class Ww1StringList liest im Ctor eine Anzahl von P-Strings aus dem Stream
819 // in den Speicher und patcht sie zu C-Strings um.
820 // Die Anzahl wird in nMax zurueckgeliefert.
821 // im Index 0 stehen alle Strings nacheinander, ab Index 1 werden
822 // die einzelnen Strings referenziert.
823 Ww1StringList::Ww1StringList( SvStream& rSt, ULONG nFc, USHORT nCb )
824 : pIdxA(0), nMax(0)
826 if( nCb > 2 ) // ueberhaupt Eintraege ?
828 SVBT16 nCountBytes;
829 DBG_ASSERT(nCb > sizeof(nCountBytes), "Ww1StringList");
830 if (rSt.Seek(nFc) == (ULONG)nFc)
831 if (rSt.Read(nCountBytes, sizeof(nCountBytes))
832 == sizeof(nCountBytes)) // Laenge steht hier nochmal
834 DBG_ASSERT(SVBT16ToShort(nCountBytes)
835 == nCb, "redundant-size missmatch");
836 // hoffentlich sind sie immer gleich
837 sal_Char* pA = new sal_Char[nCb - sizeof(nCountBytes) + 1];
838 // Alloziere PString-Array
839 //~ Ww1: new-NULL
840 if (rSt.Read(pA, nCb - sizeof(nCountBytes))
841 == (ULONG)nCb - sizeof(nCountBytes)) // lese alle
842 {}// do nothing
843 // Zaehle, wieviele Fonts enthalten
844 long nLeft = nCb - sizeof(nCountBytes);
845 sal_Char* p = pA;
846 while (1)
848 USHORT nNextSiz;
849 nNextSiz = *p + 1;
850 if(nNextSiz > nLeft)
851 break;
852 nMax++;
853 nLeft -= nNextSiz;
854 if(nLeft < 1) // naechste Laenge muss gelesen werden koennen
855 break;
856 p = p + nNextSiz;
858 if (nMax)
860 pIdxA = new sal_Char*[nMax+1]; // alloziere Index-Array
861 pIdxA[0] = pA; // Index 0 : alles
862 // ab Index 1 C-Strings
863 pIdxA[1] = pA + 1; // fuelle Index-Array
864 USHORT i = 2;
865 p = pA;
866 BYTE nL = *p;
867 while(1)
869 p += nL + 1; // Neues Laengen-Byte
870 nL = *p; // merke Laenge
871 *p = '\0'; // mach C-String draus
872 if( i > nMax )
873 break;
874 pIdxA[i] = p + 1; // Ptr auf C-String
875 i++;
878 else
879 pIdxA = 0; // Keine Eintraege -> kein Array
883 const String Ww1StringList::GetStr( USHORT nNum ) const
885 String sRet;
886 if( nNum <= nMax )
887 sRet = String( pIdxA[ nNum+1 ], RTL_TEXTENCODING_MS_1252 );
888 return sRet;
891 Ww1Bookmarks::Ww1Bookmarks(Ww1Fib& rInFib)
892 : aNames(rInFib), rFib(rInFib), nIsEnd(0)
894 pPos[0] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbkfGet(),
895 rFib.GetFIB().cbPlcfbkfGet(), FALSE);
896 nPlcIdx[0] = 0;
897 pPos[1] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbklGet(),
898 rFib.GetFIB().cbPlcfbklGet(), TRUE);
899 nPlcIdx[1] = 0;
900 bOK = !aNames.GetError() && !pPos[0]->GetError() && !pPos[1]->GetError();
903 // Der Operator ++ hat eine Tuecke: Wenn 2 Bookmarks aneinandergrenzen, dann
904 // sollte erst das Ende des ersten und dann der Anfang des 2. erreicht werden.
905 // Liegen jedoch 2 Bookmarks der Laenge 0 aufeinander, *muss* von jedem Bookmark
906 // erst der Anfang und dann das Ende gefunden werden.
907 // Der Fall: ][
908 // [...]
909 // ][
910 // ist noch nicht geloest, dabei muesste ich in den Anfangs- und Endindices
911 // vor- und zurueckspringen, wobei ein weiterer Index oder ein Bitfeld
912 // oder etwas aehnliches zum Merken der bereits abgearbeiteten Bookmarks
913 // noetig wird.
914 void Ww1Bookmarks::operator ++( int )
916 if( bOK )
918 nPlcIdx[nIsEnd]++;
920 ULONG l0 = pPos[0]->Where(nPlcIdx[0]);
921 ULONG l1 = pPos[1]->Where(nPlcIdx[1]);
922 if( l0 < l1 )
923 nIsEnd = 0;
924 else if( l1 < l0 )
925 nIsEnd = 1;
926 else
927 nIsEnd = ( nIsEnd ) ? 0 : 1;
931 long Ww1Bookmarks::GetHandle() const
933 if( bOK )
935 if( nIsEnd )
936 return nPlcIdx[1];
938 const BYTE* p = pPos[0]->GetData( nPlcIdx[0] );
939 if( p )
940 return SVBT16ToShort( p );
942 return LONG_MAX;
945 long Ww1Bookmarks::Len() const
947 if( nIsEnd )
949 DBG_ASSERT( FALSE, "Falscher Aufruf (1) von Ww1Bookmarks::Len()" );
950 return 0;
952 USHORT nEndIdx = SVBT16ToShort(pPos[0]->GetData(nPlcIdx[0]));
953 return pPos[1]->Where(nEndIdx) - pPos[0]->Where(nPlcIdx[0]);
956 const String Ww1Bookmarks::GetName() const
958 if( nIsEnd )
959 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "???" ));
960 return aNames.GetStr( nPlcIdx[0] );
963 /////////////////////////////////////////////////////////////////// Fkp
964 Ww1Fkp::Ww1Fkp(SvStream& rStream, ULONG ulFilePos, USHORT _nItemSize) :
965 nItemSize(_nItemSize),
966 bOK(FALSE)
968 if (rStream.Seek(ulFilePos) == (ULONG)ulFilePos)
969 if (rStream.Read(aFkp, sizeof(aFkp)) == sizeof(aFkp))
970 bOK = TRUE;
973 ULONG Ww1Fkp::Where(USHORT nIndex)
975 ULONG lRet = 0xffffffff;
976 DBG_ASSERT(nIndex<=Count(), "index out of bounds");
977 if (nIndex<=Count())
978 lRet = SVBT32ToUInt32(aFkp+nIndex*sizeof(SVBT32));
979 return lRet;
982 BYTE* Ww1Fkp::GetData(USHORT nIndex)
984 BYTE* pRet = NULL;
985 DBG_ASSERT(nIndex<=Count(), "index out of bounds");
986 if (nIndex<=Count())
987 pRet = aFkp + (Count()+1) * sizeof(SVBT32) +
988 nIndex * nItemSize; // beginn der strukturen
989 return pRet;
992 //////////////////////////////////////////////////////////////// FkpPap
993 BOOL Ww1FkpPap::Fill(USHORT nIndex, BYTE*& p, USHORT& rnCountBytes)
995 DBG_ASSERT( nIndex < Count(), "Ww1FkpPap::Fill() Index out of Range" );
996 USHORT nOffset = SVBT8ToByte(GetData(nIndex)) * 2;
997 if (nOffset)
999 DBG_ASSERT(nOffset>(USHORT)(Count()*sizeof(SVBT32)), "calc error");
1000 // rnCountBytes = SVBT8ToByte(aFkp+nOffset) * 2 + 1; // SH: +1 ?????
1001 rnCountBytes = SVBT8ToByte(aFkp+nOffset) * 2;
1002 nOffset += sizeof(SVBT8);
1003 if( nOffset + rnCountBytes < 511 ) // SH: Assert schlug 1 zu frueh zu
1004 rnCountBytes++; // SH: Ich weiss nicht genau,
1005 // ob das letzte Byte des PAPX
1006 // genutzt wird, aber so vergessen
1007 // wir keins und sind trotzdem
1008 // auf der sicheren Seite
1009 DBG_ASSERT(nOffset+rnCountBytes <= 511, "calc error");
1010 p = aFkp + nOffset;
1012 else
1014 p = NULL;
1015 rnCountBytes = 0;
1017 return TRUE;
1020 //////////////////////////////////////////////////////////////// FkpChp
1021 BOOL Ww1FkpChp::Fill(USHORT nIndex, W1_CHP& aChp)
1023 DBG_ASSERT( nIndex < Count(), "Ww1FkpChp::Fill() Index out of Range" );
1024 memset(&aChp, 0, sizeof(aChp)); // Default, da verkuerzt gespeichert
1025 USHORT nOffset = GetData(nIndex)[0] * 2;
1026 if (nOffset)
1028 DBG_ASSERT(nOffset>(USHORT)(Count()*sizeof(SVBT32)), "calc error");
1029 USHORT nCountBytes = aFkp[nOffset];
1030 nOffset += sizeof(SVBT8);
1031 DBG_ASSERT(nCountBytes <= 511-nOffset, "calc error");
1032 DBG_ASSERT(nCountBytes <= sizeof(aChp), "calc error");
1033 memcpy(&aChp, aFkp+nOffset, nCountBytes);
1035 return TRUE;
1038 ///////////////////////////////////////////////////////////////// Assoc
1039 Ww1Assoc::Ww1Assoc(Ww1Fib& _rFib)
1040 : rFib(_rFib), pBuffer(NULL), bOK(FALSE)
1042 USHORT cb = rFib.GetFIB().cbSttbfAssocGet();
1043 USHORT i;
1045 for ( i = 0; i < MaxFields; i++ )
1046 pStrTbl[i] = NULL;
1047 if ((pBuffer = new sal_Char[cb]) != NULL
1048 && rFib.GetStream().Seek(rFib.GetFIB().fcSttbfAssocGet()) ==
1049 rFib.GetFIB().fcSttbfAssocGet()
1050 && rFib.GetStream().Read(pBuffer, cb) == cb)
1052 USHORT j;
1053 DBG_ASSERT( cb == SVBT16ToShort( *(SVBT16*)pBuffer ), "size missmatch");
1054 for (i=0,j=sizeof(SVBT16);j<cb && i<Criteria1;i++)
1056 pStrTbl[i] = pBuffer+j;
1057 j += (*pBuffer + j) + 1;
1059 bOK = TRUE;
1063 String Ww1Assoc::GetStr(USHORT code)
1065 String sRet;
1066 DBG_ASSERT(code<MaxFields, "out of range");
1067 if (pStrTbl[code] != NULL)
1068 for( USHORT i=0;i<pStrTbl[code][0];i++ )
1069 sRet += String( pStrTbl[code][i+1], RTL_TEXTENCODING_MS_1252 );
1070 return sRet;
1073 /////////////////////////////////////////////////////////////////// Pap
1074 Ww1Pap::Ww1Pap(Ww1Fib& _rFib)
1075 : Ww1PlcPap(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0),
1076 nPushedFkpIndex(0xffff), ulOffset(0), pPap(0)
1080 void Ww1Pap::Seek(ULONG ulSeek)
1082 while (ulSeek > Where())
1083 (*this)++;
1086 // SH: Where hat einen Parameter mitbekommen, der sagt, ob bei Neuanlegen eines
1087 // Fkps der zugehoerige Index auf 0 gesetzt werden soll
1088 // ( darf fuer Push/Pop nicht passieren )
1089 // Ein eleganterer Weg faellt mir auf die Schnelle nicht ein
1090 ULONG Ww1Pap::Where( BOOL bSetIndex )
1092 ULONG ulRet = 0xffffffff;
1093 if (pPap == NULL)
1094 if (nPlcIndex < Count())
1096 pPap = new Ww1FkpPap(rFib.GetStream(),
1097 SVBT16ToShort(GetData(nPlcIndex)) << 9);
1098 if( bSetIndex )
1099 nFkpIndex = 0;
1101 if (pPap != NULL)
1102 // if (nFkpIndex < pPap->Count())
1103 if (nFkpIndex <= pPap->Count())
1104 ulRet = pPap->Where(nFkpIndex) - rFib.GetFIB().fcMinGet();
1105 return ulRet;
1108 void Ww1Pap::operator++(int)
1110 if (pPap != NULL)
1111 // if (++nFkpIndex >= pPap->Count())
1112 if (++nFkpIndex > pPap->Count())
1114 delete pPap;
1115 pPap = NULL;
1116 nPlcIndex++;
1120 // SH: FindSprm sucht in grpprl nach Sprm nId
1121 // Rueckgabe: Pointer oder 0
1122 BOOL Ww1Pap::FindSprm(USHORT nId, BYTE* pStart, BYTE* pEnd)
1124 Ww1Sprm aSprm( pStart, static_cast< USHORT >(pEnd-pStart) );
1125 USHORT nC = aSprm.Count();
1126 USHORT i;
1127 BYTE nI;
1128 USHORT nLen;
1129 BYTE *pData;
1130 for( i = 0; i < nC; i++ ){
1131 aSprm.Fill( i, nI, nLen, pData );
1132 if( nI == nId )
1133 return TRUE;
1135 return FALSE;
1138 BOOL Ww1Pap::HasId0(USHORT nId)
1140 BOOL bRet = FALSE;
1141 UpdateIdx();
1143 if( !pPap ){
1144 DBG_ASSERT( FALSE, "Ww1Pap::HasId():: kann kein pPap erzeugen" );
1145 return FALSE;
1148 BYTE* pByte;
1149 USHORT n;
1150 if( pPap->Fill(nFkpIndex, pByte, n) ){
1151 BYTE* p2 = ((W1_PAPX*)(pByte))->grpprlGet(); // SH: Offset fehlte
1152 bRet = FindSprm( nId, p2, pByte + n );
1154 return bRet;
1157 BOOL Ww1Pap::HasId(USHORT nId)
1159 BOOL bRet = FALSE;
1160 USHORT nPushedPlcIndex2 = nPlcIndex;
1161 USHORT nPushedFkpIndex2 = nFkpIndex;
1162 bRet = HasId0( nId );
1163 if (nPlcIndex != nPushedPlcIndex2)
1165 delete pPap;
1166 pPap = NULL;
1168 nPlcIndex = nPushedPlcIndex2;
1169 nFkpIndex = nPushedFkpIndex2;
1170 Where( FALSE );
1171 return bRet;
1174 /////////////////////////////////////////////////////////////////// Chp
1175 Ww1Chp::Ww1Chp(Ww1Fib& _rFib)
1176 : Ww1PlcChp(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0),
1177 nPushedFkpIndex(0xffff), ulOffset(0), pChp(0)
1181 void Ww1Chp::Seek(ULONG ulSeek)
1183 while (ulSeek > Where())
1184 (*this)++;
1187 // SH: Where hat einen Parameter mitbekommen, der sagt, ob bei Neuanlegen eines
1188 // Fkps der zugehoerige Index auf 0 gesetzt werden soll
1189 // ( darf fuer Push/Pop nicht passieren )
1190 // Ein eleganterer Weg faellt mir auf die Schnelle nicht ein
1191 ULONG Ww1Chp::Where( BOOL bSetIndex )
1193 ULONG ulRet = 0xffffffff;
1194 if (pChp == NULL)
1195 if (nPlcIndex < Count())
1197 pChp = new Ww1FkpChp(rFib.GetStream(),
1198 SVBT16ToShort(GetData(nPlcIndex)) << 9);
1199 if( bSetIndex )
1200 nFkpIndex = 0;
1202 if (pChp != NULL)
1203 // if (nFkpIndex < pChp->Count())
1204 if (nFkpIndex <= pChp->Count())
1205 ulRet = pChp->Where(nFkpIndex) -
1206 rFib.GetFIB().fcMinGet() - ulOffset;
1207 return ulRet;
1210 void Ww1Chp::operator++(int)
1212 if (pChp != NULL)
1213 // if (++nFkpIndex >= pChp->Count())
1214 if (++nFkpIndex > pChp->Count())
1216 delete pChp;
1217 pChp = NULL;
1218 nPlcIndex++;
1222 ////////////////////////////////////////////////////////////// Manager
1223 Ww1Manager::Ww1Manager(SvStream& rStrm, ULONG nFieldFlgs)
1224 : bOK(FALSE), bInTtp(FALSE), bInStyle(FALSE), bStopAll(FALSE), aFib(rStrm),
1225 aDop(aFib), aFonts(aFib, nFieldFlgs), aDoc(aFib), pDoc(&aDoc),
1226 ulDocSeek(0), pSeek(&ulDocSeek), aFld(aFib), pFld(&aFld), aChp(aFib),
1227 aPap(aFib), aFtn(aFib), aBooks(aFib),
1228 aSep(aFib, aDop.GetDOP().grpfIhdtGet())
1230 bOK = !aFib.GetError()
1231 && !aFib.GetFIB().fComplexGet()
1232 && !aDoc.GetError()
1233 && !aSep.GetError()
1234 && !aPap.GetError()
1235 && !aChp.GetError()
1236 && !aFld.GetError()
1237 && !aFtn.GetError()
1238 && !aBooks.GetError();
1241 BOOL Ww1Manager::HasInTable()
1243 return aPap.HasId(24); // Ww1SingleSprmPFInTable
1246 BOOL Ww1Manager::HasTtp()
1248 return aPap.HasId(25); // Ww1SingleSprmPTtp
1251 BOOL Ww1Manager::HasPPc()
1253 return aPap.HasId(29); // Ww1SingleSprmPPc
1256 BOOL Ww1Manager::HasPDxaAbs()
1258 return aPap.HasId(26); // Ww1SingleSprmPDxaAbs