LCOV - code coverage report
Current view: top level - sw/source/filter/ww1 - w1class.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 682 0.0 %
Date: 2014-04-11 Functions: 0 72 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string.h>
      21             : #include <rtl/strbuf.hxx>
      22             : #include <rtl/ustring.hxx>
      23             : #include <tools/stream.hxx>
      24             : #include <w1class.hxx>
      25             : 
      26             : #ifdef DUMP
      27             : static const sal_Char* pUnknown = "?";
      28             : #define DUMPNAME(s) s
      29             : #else
      30             : #define DUMPNAME(s) 0
      31             : #endif
      32             : 
      33             : Ww1SingleSprm* Ww1Sprm::aTab[ 256 ];
      34             : Ww1SingleSprm* Ww1Sprm::pSingleSprm = 0;
      35             : 
      36             : // Fib
      37           0 : Ww1Fib::Ww1Fib( SvStream& _rStream )
      38           0 :     : rStream(_rStream)
      39             : {
      40           0 :     bOK = 0 == rStream.Seek(0) &&
      41           0 :           rStream.Read( &aFib, sizeof( aFib )) == sizeof( aFib );
      42           0 : }
      43             : 
      44             : // PlainText
      45           0 : Ww1PlainText::Ww1PlainText(Ww1Fib& rWwFib, sal_uLong nFilePos, sal_uLong nCountBytes)
      46             :     : rFib(rWwFib), ulFilePos(nFilePos), ulCountBytes(nCountBytes),
      47           0 :     ulSeek(0), bOK(true)
      48             : {
      49           0 : }
      50             : 
      51           0 : sal_Unicode Ww1PlainText::operator [] ( sal_uLong ulOffset )
      52             : {
      53             :     OSL_ENSURE( ulOffset<Count(), "Ww1PlainText" );
      54             :     sal_Unicode cRet;
      55             :     sal_Char cRead;
      56           0 :     if( rFib.GetStream().Seek( ulFilePos + ulOffset ) == ulFilePos+ulOffset &&
      57           0 :         rFib.GetStream().Read( &cRead, sizeof( cRead ) ) == sizeof( cRead ) )
      58             :     {
      59           0 :         cRet = OUString(&cRead, 1, RTL_TEXTENCODING_MS_1252).toChar();
      60             :     }
      61             :     else
      62           0 :         cRet = ' ';
      63           0 :     return cRet;
      64             : }
      65             : 
      66           0 : OUString Ww1PlainText::GetText( sal_uLong ulOffset, sal_uLong nLen ) const
      67             : {
      68             :     OSL_ENSURE(ulOffset+nLen<Count(), "Ww1PlainText");
      69             : 
      70           0 :     sal_Size nPos = ulFilePos+ulOffset;
      71             : 
      72           0 :     bool bSeekOk = rFib.GetStream().Seek(nPos) == nPos;
      73             :     return bSeekOk ?
      74           0 :         read_uInt8s_ToOUString(rFib.GetStream(), nLen, RTL_TEXTENCODING_MS_1252) :
      75           0 :         OUString();
      76             : }
      77             : 
      78             : // Style
      79           0 : Ww1Style::Ww1Style()
      80           0 :     : pPapx(0), pParent(0), stcBase(0), stcNext(0), bUsed(false)
      81             : {
      82           0 : }
      83             : 
      84           0 : Ww1Style::~Ww1Style()
      85             : {
      86           0 :     delete pPapx;
      87           0 : }
      88             : 
      89           0 : void Ww1Style::SetDefaults(sal_uInt8 stc)
      90             : {
      91           0 :     if( 222 == stc )
      92             :     {
      93           0 :         stcBase = 222;
      94           0 :         stcNext = 222;
      95           0 :         aChpx.hpsSet(20);
      96             :     }
      97           0 : }
      98             : 
      99           0 : sal_uInt16 Ww1Style::ReadName( sal_uInt8*&p, sal_uInt16& rnCountBytes, sal_uInt16 stc )
     100             : {
     101           0 :     sal_uInt8 nCountBytes = *p;
     102           0 :     p++;
     103           0 :     rnCountBytes--;
     104           0 :     if( !nCountBytes ) // default
     105             :     {
     106             :         static const sal_Char* const names[] =
     107             :         {
     108             :             "W1 Null",  //222
     109             :             "W1 Annotation reference",  //223
     110             :             "W1 Annotation text",  //224
     111             :             "W1 Table of contents 8",  //225
     112             :             "W1 Table of contents 7",  //226
     113             :             "W1 Table of contents 6",  //227
     114             :             "W1 Table of contents 5",  //228
     115             :             "W1 Table of contents 4",  //229
     116             :             "W1 Table of contents 3",  //230
     117             :             "W1 Table of contents 2",  //231
     118             :             "W1 Table of contents 1",  //232
     119             :             "W1 Index 7",  //233
     120             :             "W1 Index 6",  //234
     121             :             "W1 Index 5",  //235
     122             :             "W1 Index 4",  //236
     123             :             "W1 Index 3",  //237
     124             :             "W1 Index 2",  //238
     125             :             "W1 Index 1",  //239
     126             :             "W1 Line number",  //240
     127             :             "W1 Index heading",  //241
     128             :             "W1 Footer",  //242
     129             :             "W1 Header",  //243
     130             :             "W1 Footnote reference",  //244
     131             :             "W1 Footnote text",  //245
     132             :             "W1 Heading 9",  //246
     133             :             "W1 Heading 8",  //247
     134             :             "W1 Heading 7",  //248
     135             :             "W1 Heading 6",  //249
     136             :             "W1 Heading 5",  //250
     137             :             "W1 Heading 4",  //251
     138             :             "W1 Heading 3",  //252
     139             :             "W1 Heading 2",  //253
     140             :             "W1 Heading 1",  //254
     141             :             "W1 Normal indent"  //255
     142             :             };//256
     143             : 
     144             :         const sal_Char* pStr;
     145           0 :         size_t nSize(stc);
     146           0 :         if (!nSize)
     147           0 :             pStr = "W1 Normal";
     148           0 :         else if (nSize - 222 >= SAL_N_ELEMENTS(names))
     149           0 :             pStr = "?";
     150             :         else
     151           0 :             pStr = names[nSize-222];
     152           0 :         SetName(OUString(pStr, strlen(pStr), RTL_TEXTENCODING_MS_1252));
     153             :     }
     154           0 :     else if( 255 > nCountBytes ) // unused
     155             :     {
     156           0 :         SetName( OUString( (sal_Char*)p, nCountBytes, RTL_TEXTENCODING_MS_1252 ));
     157           0 :         p += nCountBytes;
     158             :         OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1Style");
     159           0 :         rnCountBytes = rnCountBytes - nCountBytes;
     160             :     }
     161           0 :     return 0;
     162             : }
     163             : 
     164           0 : sal_uInt16 Ww1Style::ReadChpx( sal_uInt8*&p, sal_uInt16& rnCountBytes )
     165             : {
     166           0 :     sal_uInt16 nCountBytes = *p;
     167           0 :     p++;
     168           0 :     rnCountBytes--;
     169           0 :     if (nCountBytes != 255 // unused
     170           0 :      && nCountBytes != 0) // default
     171             :     {
     172           0 :         if (nCountBytes > sizeof(aChpx))
     173           0 :             nCountBytes = sizeof(aChpx);
     174           0 :         memcpy( &aChpx, p, nCountBytes );
     175           0 :         p += nCountBytes;
     176             :         OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1Style");
     177           0 :         rnCountBytes = rnCountBytes - nCountBytes;
     178             :     }
     179           0 :     return 0;
     180             : }
     181             : 
     182           0 : sal_uInt16 Ww1Style::ReadPapx(sal_uInt8*&p, sal_uInt16& rnCountBytes)
     183             : {
     184           0 :     sal_uInt16 nCountBytes = *p;
     185           0 :     p++;
     186           0 :     rnCountBytes--;
     187           0 :     if (nCountBytes != 255)
     188             :     {
     189           0 :         pPapx = new Ww1SprmPapx(p, nCountBytes);
     190           0 :         p += nCountBytes;
     191             :         OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1Style");
     192           0 :         rnCountBytes = rnCountBytes - nCountBytes;
     193             :     }
     194             :     else
     195           0 :         pPapx = new Ww1SprmPapx(p, 0);
     196           0 :     return 0;
     197             : }
     198             : 
     199           0 : sal_uInt16 Ww1Style::ReadEstcp(sal_uInt8*&p, sal_uInt16& rnCountBytes)
     200             : {
     201           0 :     stcNext = *p;
     202           0 :     p++;
     203           0 :     rnCountBytes--;
     204           0 :     stcBase = *p;
     205           0 :     p++;
     206             :     OSL_ENSURE(rnCountBytes>0, "Ww1Style");
     207           0 :     rnCountBytes--;
     208           0 :     return 0;
     209             : }
     210             : 
     211             : // StyleSheet
     212           0 : Ww1StyleSheet::Ww1StyleSheet(Ww1Fib& _rFib)
     213             :     : cstcStd(0),
     214             :     rFib(_rFib),
     215           0 :     bOK(sal_False)
     216             : {
     217           0 :     sal_uInt16 cbStshf = rFib.GetFIB().cbStshfGet();
     218             :     OSL_ENSURE(cbStshf>=17, "Ww1StyleSheet");
     219           0 :     for (sal_uInt16 stc=0;stc<Count();stc++)
     220             :     {
     221           0 :         aStyles[stc].SetParent(this);
     222           0 :         aStyles[stc].SetDefaults((sal_uInt8)stc);
     223             :     }
     224           0 :     sal_uInt8* del = NULL;
     225           0 :     if (rFib.GetStream().Seek(rFib.GetFIB().fcStshfGet())
     226           0 :       == (sal_uLong)rFib.GetFIB().fcStshfGet()
     227           0 :      && (del = new sal_uInt8[cbStshf]) != NULL
     228           0 :      && rFib.GetStream().Read(del, cbStshf) == (sal_uLong)cbStshf)
     229             :         {
     230           0 :         sal_uInt8* p = del;
     231           0 :             cstcStd = SVBT16ToShort(p);
     232           0 :             p += sizeof(SVBT16);
     233           0 :             cbStshf -= sizeof(SVBT16);
     234           0 :             ReadNames(p, cbStshf);
     235           0 :             ReadChpx(p, cbStshf);
     236           0 :             ReadPapx(p, cbStshf);
     237           0 :             ReadEstcp(p, cbStshf);
     238             :             OSL_ENSURE(cbStshf==0, "Ww1StyleSheet");
     239           0 :             bOK = cbStshf == 0;
     240             :         }
     241           0 :     delete [] del;
     242           0 : }
     243             : 
     244           0 : sal_uInt16 Ww1StyleSheet::ReadNames( sal_uInt8*& p, sal_uInt16& rnCountBytes )
     245             : {
     246           0 :     sal_uInt16 nCountBytes = SVBT16ToShort(p);
     247           0 :     p += sizeof(SVBT16);
     248             :     OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
     249           0 :     rnCountBytes = rnCountBytes - nCountBytes;
     250           0 :     nCountBytes = nCountBytes - sizeof(SVBT16);
     251           0 :     sal_uInt16 stcp = 0;
     252           0 :     while (nCountBytes > 0)
     253             :     {
     254           0 :         sal_uInt16 stc = (stcp - cstcStd) & 255;
     255           0 :         aStyles[stc].ReadName(p, nCountBytes, stc);
     256           0 :         stcp++;
     257             :     }
     258             :     OSL_ENSURE(nCountBytes==0, "Ww1StyleSheet");
     259           0 :     return 0;
     260             : }
     261             : 
     262           0 : sal_uInt16 Ww1StyleSheet::ReadChpx(sal_uInt8*& p, sal_uInt16& rnCountBytes)
     263             : {
     264           0 :     sal_uInt16 nCountBytes = SVBT16ToShort(p);
     265           0 :     p += sizeof(SVBT16);
     266             :     OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
     267           0 :     rnCountBytes = rnCountBytes - nCountBytes;
     268           0 :     nCountBytes = nCountBytes - sizeof(SVBT16);
     269           0 :     sal_uInt16 stcp = 0;
     270           0 :     while (nCountBytes > 0)
     271             :     {
     272           0 :         sal_uInt16 stc = (stcp - cstcStd) & 255;
     273           0 :         aStyles[stc].ReadChpx(p, nCountBytes);
     274           0 :         stcp++;
     275             :     }
     276             :     OSL_ENSURE(nCountBytes == 0, "Ww1StyleSheet");
     277           0 :     return 0;
     278             : }
     279             : 
     280           0 : sal_uInt16 Ww1StyleSheet::ReadPapx(sal_uInt8*& p, sal_uInt16& rnCountBytes)
     281             : {
     282           0 :     sal_uInt16 nCountBytes = SVBT16ToShort(p);
     283           0 :     p += sizeof(SVBT16);
     284             :     OSL_ENSURE(rnCountBytes>=nCountBytes, "Ww1StyleSheet");
     285           0 :     rnCountBytes = rnCountBytes - nCountBytes;
     286           0 :     nCountBytes = nCountBytes - sizeof(SVBT16);
     287           0 :     sal_uInt16 stcp = 0;
     288           0 :     while (nCountBytes > 0)
     289             :     {
     290           0 :         sal_uInt16 stc = (stcp - cstcStd) & 255;
     291           0 :         aStyles[stc].ReadPapx(p, nCountBytes);
     292           0 :         stcp++;
     293             :     }
     294             :     OSL_ENSURE(nCountBytes == 0, "Ww1StyleSheet");
     295           0 :     return 0;
     296             : }
     297             : 
     298           0 : sal_uInt16 Ww1StyleSheet::ReadEstcp(sal_uInt8*& p, sal_uInt16& rnCountBytes)
     299             : {
     300           0 :     sal_uInt16 iMac = SVBT16ToShort(p);
     301           0 :     p += sizeof(SVBT16);
     302             :     OSL_ENSURE(rnCountBytes>=sizeof(SVBT16), "Ww1StyleSheet");
     303           0 :     rnCountBytes -= sizeof(SVBT16);
     304           0 :     for (sal_uInt16 stcp=0;stcp<iMac;stcp++)
     305             :     {
     306           0 :         sal_uInt16 stc = (stcp - cstcStd) & 255;
     307           0 :         aStyles[stc].ReadEstcp(p, rnCountBytes);
     308             :     }
     309             :     OSL_ENSURE(rnCountBytes==0, "Ww1StyleSheet");
     310           0 :     return 0;
     311             : }
     312             : 
     313             : // Fonts
     314           0 : Ww1Fonts::Ww1Fonts(Ww1Fib& rInFib, sal_uLong nFieldFlgs)
     315           0 :     : pFontA(0), rFib(rInFib), nFieldFlags(nFieldFlgs), nMax(0), bOK(false)
     316             : {
     317           0 :     if(rFib.GetFIB().cbSttbfffnGet() > 2 ) // any fonts at all?
     318             :     {
     319             :         SVBT16 nCountBytes;
     320             :         OSL_ENSURE(rFib.GetFIB().cbSttbfffnGet() > sizeof(nCountBytes), "Ww1Fonts");
     321           0 :         if (rFib.GetStream().Seek(rFib.GetFIB().fcSttbfffnGet())
     322           0 :          == (sal_uLong)rFib.GetFIB().fcSttbfffnGet())
     323           0 :             if (rFib.GetStream().Read(nCountBytes, sizeof(nCountBytes))
     324             :              == sizeof(nCountBytes)) // length is repeated here
     325             :             {
     326             :                 OSL_ENSURE(SVBT16ToShort(nCountBytes)
     327             :                  == rFib.GetFIB().cbSttbfffnGet(), "redundant-size missmatch");
     328             :                  // hopefully they're always equal
     329           0 :                 W1_FFN* pA = (W1_FFN*)new char[rFib.GetFIB().cbSttbfffnGet()
     330           0 :                  - sizeof(nCountBytes)]; // allocate Font-Array
     331             :                 //~ Ww1: new-NULL
     332           0 :                 if (rFib.GetStream().Read(pA, rFib.GetFIB().cbSttbfffnGet()
     333           0 :                  - sizeof(nCountBytes)) == (sal_uLong)rFib.GetFIB().cbSttbfffnGet()
     334           0 :                  - sizeof(nCountBytes)) // read all Fonts
     335             :                 {} // nothing
     336             : 
     337           0 :                 long nLeft = rFib.GetFIB().cbSttbfffnGet()
     338           0 :                  - sizeof(nCountBytes); // count how many contain fonts
     339           0 :                 W1_FFN* p = pA;
     340             :                 while (true)
     341             :                 {
     342             :                     sal_uInt16 nNextSiz;
     343           0 :                     nNextSiz = p->cbFfnM1Get() + 1;
     344           0 :                     if(nNextSiz > nLeft)
     345           0 :                         break;
     346           0 :                     nMax++;
     347           0 :                     nLeft -= nNextSiz;
     348           0 :                     if(nLeft < 1)           // need to be able to read next length
     349           0 :                         break;
     350           0 :                     p = (W1_FFN *)(((char*)p) + nNextSiz);
     351             :                 }
     352           0 :                 if (nMax)
     353             :                 {
     354           0 :                     pFontA = new W1_FFN*[nMax];         // allocate Index-Array
     355             :                     //~ Ww1: new-NULL
     356           0 :                     pFontA[0] = pA;                     // fill Index-Array
     357             :                     sal_uInt16 i;
     358           0 :                     for(i=1, p=pA; i<nMax; i++)
     359             :                     {
     360           0 :                         p = (W1_FFN*)(((char*)p) + p->cbFfnM1Get() + 1);
     361           0 :                         pFontA[i] = p;
     362             :                     }
     363             :                 }
     364             :                 else
     365           0 :                     pFontA = 0; // no entries -> no Array
     366             :             }
     367             :     }
     368           0 :     bOK = sal_True;
     369           0 : }
     370             : 
     371           0 : W1_FFN* Ww1Fonts::GetFFN(sal_uInt16 nNum)
     372             : {
     373           0 :     W1_FFN* pRet = NULL;
     374           0 :     if (pFontA)
     375           0 :         if (nNum < nMax)
     376           0 :             pRet = pFontA[nNum];
     377           0 :     return pRet;
     378             : }
     379             : 
     380             : // DOP
     381           0 : Ww1Dop::Ww1Dop(Ww1Fib& _rFib)
     382           0 :     : rFib(_rFib)
     383             : {
     384             :     long nRead;
     385           0 :     memset(&aDop, 0, sizeof(aDop)); // set defaults
     386           0 :     if(rFib.GetFIB().cbDopGet() >= sizeof(aDop))
     387           0 :         nRead = sizeof(aDop);
     388             :     else
     389           0 :         nRead = rFib.GetFIB().cbDopGet();
     390           0 :     bOK = rFib.GetStream().Seek(rFib.GetFIB().fcDopGet()) ==
     391           0 :                 (sal_uLong)rFib.GetFIB().fcDopGet() &&
     392           0 :             rFib.GetStream().Read(&aDop, nRead) == (sal_uLong)nRead;
     393           0 : }
     394             : 
     395             : // Picture
     396           0 : Ww1Picture::Ww1Picture(SvStream& rStream, sal_uLong ulFilePos)
     397           0 :     : bOK(false), pPic(0)
     398             : {
     399           0 :     ulFilePos &= 0xffffff; //~ ww1: for some reason the high byte contains 5?!?!
     400             :     SVBT32 lcb;
     401           0 :     if (rStream.Seek(ulFilePos) == (sal_uLong)ulFilePos)
     402           0 :         if (rStream.Read(&lcb, sizeof(lcb)) == (sal_uLong)sizeof(lcb))
     403           0 :             if (sizeof(int)>=4 || SVBT32ToUInt32(lcb) < 0x8000) //~ mdt: 64K & 16bit
     404           0 :                 if ((pPic = (W1_PIC*)(new sal_uInt8[SVBT32ToUInt32(lcb)])) != NULL)
     405           0 :                     if (rStream.Seek(ulFilePos) == (sal_uLong)ulFilePos)
     406           0 :                         if (rStream.Read(pPic, SVBT32ToUInt32(lcb)) == (sal_uLong)SVBT32ToUInt32(lcb))
     407             :                         {
     408             :                             OSL_ENSURE(pPic->cbHeaderGet()==sizeof(*pPic)-sizeof(pPic->rgb), "Ww1Picture");
     409           0 :                             bOK = true;
     410             :                         }
     411           0 : }
     412             : 
     413             : // Sprm
     414           0 : Ww1Sprm::Ww1Sprm(sal_uInt8* x, sal_uInt16 _nCountBytes)
     415             :     : p(NULL),
     416             :     nCountBytes(_nCountBytes),
     417             :     bOK(sal_False),
     418             :     pArr(NULL),
     419           0 :     count(0)
     420             : {
     421           0 :     if (nCountBytes == 0)
     422           0 :         bOK = sal_True;
     423             :     else
     424           0 :         if ((p = new sal_uInt8[nCountBytes]) != NULL)
     425             :         {
     426           0 :             memcpy(p, x, nCountBytes);
     427           0 :             if (ReCalc())
     428           0 :                 bOK = sal_True;
     429             :         }
     430           0 : }
     431             : 
     432           0 : Ww1Sprm::Ww1Sprm(SvStream& rStream, sal_uLong ulFilePos)
     433             :     : p(NULL),
     434             :     nCountBytes(0),
     435             :     bOK(sal_False),
     436             :     pArr(NULL),
     437           0 :     count(0)
     438             : {
     439           0 :     sal_uInt8 x = 0;
     440           0 :     if (rStream.Seek(ulFilePos) == (sal_uLong)ulFilePos)
     441           0 :         if (rStream.Read(&x, sizeof(x)) == (sal_uLong)sizeof(x))
     442           0 :             if ((nCountBytes = x) == 255
     443           0 :              || !nCountBytes
     444           0 :              || (p = new sal_uInt8[nCountBytes]) != NULL)
     445           0 :                 if (nCountBytes == 255
     446           0 :                  || !nCountBytes
     447           0 :                  || rStream.Read(p, nCountBytes) == (sal_uLong)nCountBytes)
     448           0 :                     if (ReCalc())
     449           0 :                         bOK = sal_True;
     450           0 : }
     451             : 
     452           0 : Ww1Sprm::~Ww1Sprm()
     453             : {
     454           0 :     delete[] pArr;
     455           0 :     delete[] p;
     456           0 : }
     457             : 
     458           0 : sal_uInt16 Ww1SingleSprm::Size(sal_uInt8* /*pSprm*/)
     459             : {
     460           0 :     return nCountBytes;
     461             : }
     462             : 
     463           0 : Ww1SingleSprm::~Ww1SingleSprm()
     464             : {
     465           0 : }
     466             : 
     467           0 : sal_uInt16 Ww1SingleSprmTab::Size(sal_uInt8* pSprm) // Doc 24/25, Fastsave-Sprm
     468             : {
     469             :     OSL_ENSURE(nCountBytes==0, "Ww1SingleSprmTab");
     470           0 :     sal_uInt16 nRet = sizeof(sal_uInt8);
     471           0 :     sal_uInt16 nSize = *pSprm;
     472           0 :     if (nSize != 255)
     473           0 :         nRet = nRet + nSize;
     474             :     else
     475             :     {
     476           0 :         sal_uInt16 nDel = (*(pSprm + 1)) * 4;
     477           0 :         sal_uInt16 nIns = (*(pSprm + 3 + nDel)) * 3;
     478           0 :         nRet += nDel + nIns;
     479             :     }
     480             :     OSL_ENSURE(nRet <= 354, "Ww1SingleSprmTab");
     481           0 :     if (nRet > 354)
     482           0 :         nRet = 0;
     483           0 :     return nRet;
     484             : }
     485             : 
     486           0 : sal_uInt16 Ww1SingleSprmByteSized::Size(sal_uInt8* pSprm)
     487             : {
     488           0 :     sal_uInt16 nRet = *pSprm + sizeof(sal_uInt8) + nCountBytes;
     489           0 :     return nRet;
     490             : }
     491             : 
     492           0 : sal_uInt16 Ww1SingleSprmWordSized::Size(sal_uInt8* pSprm)
     493             : {
     494             :     sal_uInt16 nRet;
     495           0 :     nRet = SVBT16ToShort(pSprm);
     496           0 :     nRet += sizeof(SVBT16);  // var. l. word-size
     497           0 :     nRet = nRet + nCountBytes;
     498           0 :     return nRet;
     499             : }
     500             : 
     501             : static sal_uInt8 nLast = 0;
     502             : static sal_uInt8 nCurrent = 0;
     503           0 : sal_uInt16 Ww1Sprm::GetSize(sal_uInt8 nId, sal_uInt8* pSprm)
     504             : {
     505           0 :     sal_uInt16 nL = 0;
     506           0 :     nL = GetTab(nId).Size(pSprm);
     507           0 :     nLast = nCurrent;
     508           0 :     nCurrent = nId;
     509           0 :     return nL;
     510             : }
     511             : 
     512           0 : sal_Bool Ww1Sprm::Fill(sal_uInt16 index, sal_uInt8& nId, sal_uInt16& nL, sal_uInt8*& pSprm)
     513             : {
     514             :     OSL_ENSURE(index < Count(), "Ww1Sprm");
     515           0 :     pSprm = p + pArr[index];
     516           0 :     nId = *pSprm;
     517           0 :     pSprm++;
     518           0 :     nL = GetTab(nId).Size(pSprm);
     519           0 :     return sal_True;
     520             : }
     521             : 
     522           0 : sal_Bool Ww1Sprm::ReCalc()
     523             : {
     524           0 :     sal_Bool bRet = sal_True;
     525           0 :     delete[] pArr;
     526           0 :     pArr = NULL;
     527           0 :     count = 0;
     528           0 :     if (nCountBytes != 255) // not unused?
     529             :     {
     530           0 :         sal_uInt16 cbsik = nCountBytes;
     531           0 :         sal_uInt8* psik = p;
     532           0 :         while (cbsik > 0)
     533             :         {
     534           0 :             sal_uInt16 iLen = GetSizeBrutto(psik);
     535             :             OSL_ENSURE(iLen<=cbsik, "Ww1Sprm");
     536           0 :             if (iLen > cbsik)
     537           0 :                 cbsik = 0; // ignore the rest: we are wrong...
     538             :             else
     539             :             {
     540           0 :                 psik += iLen;
     541           0 :                 cbsik = cbsik - iLen;
     542           0 :                 count++;
     543             :             }
     544             :         }
     545           0 :         if (bRet
     546           0 :          && (pArr = new sal_uInt16[count]) != NULL)
     547             :         {
     548           0 :             cbsik = nCountBytes;
     549           0 :             sal_uInt16 offset = 0;
     550           0 :             sal_uInt16 current = 0;
     551           0 :             psik = p;
     552           0 :             while (current<count)
     553             :             {
     554           0 :                 pArr[current++] = offset;
     555           0 :                 sal_uInt16 iLen = GetSizeBrutto(psik);
     556           0 :                 psik += iLen;
     557           0 :                 if (iLen > cbsik)
     558           0 :                     cbsik = 0;
     559             :                 else
     560           0 :                     cbsik = cbsik - iLen;
     561           0 :                 offset = offset + iLen;
     562             :             }
     563             : 
     564             :         }
     565             :         else
     566           0 :             count = 0;
     567             :     }
     568           0 :     return bRet;
     569             : }
     570             : 
     571           0 : void Ww1Sprm::DeinitTab()
     572             : {
     573           0 :     for (size_t i=0; i < SAL_N_ELEMENTS(aTab); ++i)
     574           0 :         delete aTab[i];
     575           0 :     memset(aTab, 0, SAL_N_ELEMENTS(aTab));
     576           0 :     delete pSingleSprm;
     577           0 : }
     578             : 
     579           0 : void Ww1Sprm::InitTab()
     580             : {
     581           0 :     memset(aTab, 0, SAL_N_ELEMENTS(aTab));
     582           0 :     pSingleSprm = new Ww1SingleSprm( 0, DUMPNAME(pUnknown));
     583             : 
     584           0 :     aTab[  2] = new Ww1SingleSprmByte(DUMPNAME("sprmPStc")); //   2 pap.istd (style code)
     585           0 :     aTab[  3] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPIstdPermute")); //   3 pap.istd    permutation
     586           0 :     aTab[  4] = new Ww1SingleSprmByte(DUMPNAME("sprmPIncLevel")); //   4 pap.istddifference
     587           0 :     aTab[  5] = new Ww1SingleSprmPJc(DUMPNAME("sprmPJc")); //   5 pap.jc (justification)
     588           0 :     aTab[  6] = new Ww1SingleSprmBool(DUMPNAME("sprmPFSideBySide")); //   6 pap.fSideBySide
     589           0 :     aTab[  7] = new Ww1SingleSprmPFKeep(DUMPNAME("sprmPFKeep")); //   7 pap.fKeep
     590           0 :     aTab[  8] = new Ww1SingleSprmPFKeepFollow(DUMPNAME("sprmPFKeepFollow")); //   8 pap.fKeepFollow
     591           0 :     aTab[  9] = new Ww1SingleSprmPPageBreakBefore(DUMPNAME("sprmPPageBreakBefore")); //   9 pap.fPageBreakBefore
     592           0 :     aTab[ 10] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcl")); //  10 pap.brcl
     593           0 :     aTab[ 11] = new Ww1SingleSprmByte(DUMPNAME("sprmPBrcp")); //  11 pap.brcp
     594           0 :     aTab[ 12] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPAnld")); //  12 pap.anld (ANLD structure)
     595           0 :     aTab[ 13] = new Ww1SingleSprmByte(DUMPNAME("sprmPNLvlAnm")); //  13 pap.nLvlAnm nn
     596           0 :     aTab[ 14] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoLineNumb")); //  14 ap.fNoLnn
     597           0 :     aTab[ 15] = new Ww1SingleSprmPChgTabsPapx(DUMPNAME("sprmPChgTabsPapx")); //  15 pap.itbdMac, ...
     598           0 :     aTab[ 16] = new Ww1SingleSprmPDxaRight(DUMPNAME("sprmPDxaRight")); //  16 pap.dxaRight
     599           0 :     aTab[ 17] = new Ww1SingleSprmPDxaLeft(DUMPNAME("sprmPDxaLeft")); //  17 pap.dxaLeft
     600           0 :     aTab[ 18] = new Ww1SingleSprmWord(DUMPNAME("sprmPNest")); //  18 pap.dxaNest
     601           0 :     aTab[ 19] = new Ww1SingleSprmPDxaLeft1(DUMPNAME("sprmPDxaLeft1")); //  19 pap.dxaLeft1
     602           0 :     aTab[ 20] = new Ww1SingleSprmPDyaLine(DUMPNAME("sprmPDyaLine")); //  20 pap.lspd    an LSPD
     603           0 :     aTab[ 21] = new Ww1SingleSprmPDyaBefore(DUMPNAME("sprmPDyaBefore")); //  21 pap.dyaBefore
     604           0 :     aTab[ 22] = new Ww1SingleSprmPDyaAfter(DUMPNAME("sprmPDyaAfter")); //  22 pap.dyaAfter
     605           0 :     aTab[ 23] = new Ww1SingleSprmTab(0, DUMPNAME(pUnknown)); // 23 pap.itbdMac, pap.rgdxaTab
     606           0 :     aTab[ 24] = new Ww1SingleSprmPFInTable(DUMPNAME("sprmPFInTable")); //  24 pap.fInTable
     607           0 :     aTab[ 25] = new Ww1SingleSprmPTtp(DUMPNAME("sprmPTtp")); //  25 pap.fTtp
     608           0 :     aTab[ 26] = new Ww1SingleSprmPDxaAbs(DUMPNAME("sprmPDxaAbs")); //  26 pap.dxaAbs
     609           0 :     aTab[ 27] = new Ww1SingleSprmPDyaAbs(DUMPNAME("sprmPDyaAbs")); //  27 pap.dyaAbs
     610           0 :     aTab[ 28] = new Ww1SingleSprmPDxaWidth(DUMPNAME("sprmPDxaWidth")); //  28 pap.dxaWidth
     611           0 :     aTab[ 29] = new Ww1SingleSprmPpc(DUMPNAME("sprmPPc")); //  29 pap.pcHorz, pap.pcVert
     612           0 :     aTab[ 30] = new Ww1SingleSprmPBrc10(BRC_TOP, DUMPNAME("sprmPBrcTop10")); //  30 pap.brcTop BRC10
     613           0 :     aTab[ 31] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcLeft10")); //  31 pap.brcLeft BRC10
     614           0 :     aTab[ 32] = new Ww1SingleSprmPBrc10(BRC_BOTTOM, DUMPNAME("sprmPBrcBottom10")); //  32 pap.brcBottom BRC10
     615           0 :     aTab[ 33] = new Ww1SingleSprmPBrc10(BRC_RIGHT, DUMPNAME("sprmPBrcRight10")); //  33 pap.brcRight BRC10
     616           0 :     aTab[ 34] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween10")); //  34 pap.brcBetween BRC10
     617           0 :     aTab[ 35] = new Ww1SingleSprmPBrc10(BRC_LEFT, DUMPNAME("sprmPBrcBar10")); //  35 pap.brcBar BRC10
     618           0 :     aTab[ 36] = new Ww1SingleSprmPFromText(DUMPNAME("sprmPFromText10")); //  36 pap.dxaFromText dxa
     619           0 :     aTab[ 37] = new Ww1SingleSprmByte(DUMPNAME("sprmPWr")); //  37 pap.wr wr
     620           0 :     aTab[ 38] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcTop")); //  38 pap.brcTop BRC
     621           0 :     aTab[ 39] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcLeft")); //  39 pap.brcLeft BRC
     622           0 :     aTab[ 40] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBottom")); //  40 pap.brcBottom BRC
     623           0 :     aTab[ 41] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcRight")); //  41 pap.brcRight BRC
     624           0 :     aTab[ 42] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBetween")); //  42 pap.brcBetween BRC
     625           0 :     aTab[ 43] = new Ww1SingleSprmWord(DUMPNAME("sprmPBrcBar")); //  43 pap.brcBar BRC word
     626           0 :     aTab[ 44] = new Ww1SingleSprmBool(DUMPNAME("sprmPFNoAutoHyph")); //  44 pap.fNoAutoHyph
     627           0 :     aTab[ 45] = new Ww1SingleSprmWord(DUMPNAME("sprmPWHeightAbs")); //  45 pap.wHeightAbs w
     628           0 :     aTab[ 46] = new Ww1SingleSprmWord(DUMPNAME("sprmPDcs")); //  46 pap.dcs DCS
     629           0 :     aTab[ 47] = new Ww1SingleSprmWord(DUMPNAME("sprmPShd")); //  47 pap.shd SHD
     630           0 :     aTab[ 48] = new Ww1SingleSprmWord(DUMPNAME("sprmPDyaFromText")); //  48 pap.dyaFromText dya
     631           0 :     aTab[ 49] = new Ww1SingleSprmWord(DUMPNAME("sprmPDxaFromText")); //  49 pap.dxaFromText dxa
     632           0 :     aTab[ 50] = new Ww1SingleSprmBool(DUMPNAME("sprmPFLocked")); //  50 pap.fLocked 0 or 1 byte
     633           0 :     aTab[ 51] = new Ww1SingleSprmBool(DUMPNAME("sprmPFWidowControl")); //  51 pap.fWidowControl 0 or 1 byte
     634             : 
     635           0 :     aTab[ 57] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmCDefault")); //  57 whole CHP (see below) none variable length
     636           0 :     aTab[ 58] = new Ww1SingleSprm(0, DUMPNAME("sprmCPlain")); //  58 whole CHP (see below) none 0
     637             : 
     638           0 :     aTab[ 60] = new Ww1SingleSprm4State(DUMPNAME("sprmCFBold")); //  60 chp.fBold 0,1, 128, or 129 (see below) byte
     639           0 :     aTab[ 61] = new Ww1SingleSprm4State(DUMPNAME("sprmCFItalic")); //  61 chp.fItalic 0,1, 128, or 129 (see below) byte
     640           0 :     aTab[ 62] = new Ww1SingleSprm4State(DUMPNAME("sprmCFStrike")); //  62 chp.fStrike 0,1, 128, or 129 (see below) byte
     641           0 :     aTab[ 63] = new Ww1SingleSprm4State(DUMPNAME("sprmCFOutline")); //  63 chp.fOutline 0,1, 128, or 129 (see below) byte
     642           0 :     aTab[ 64] = new Ww1SingleSprm4State(DUMPNAME("sprmCFShadow")); //  64 chp.fShadow 0,1, 128, or 129 (see below) byte
     643           0 :     aTab[ 65] = new Ww1SingleSprm4State(DUMPNAME("sprmCFSmallCaps")); //  65 chp.fSmallCaps 0,1, 128, or 129 (see below) byte
     644           0 :     aTab[ 66] = new Ww1SingleSprm4State(DUMPNAME("sprmCFCaps")); //  66 chp.fCaps 0,1, 128, or 129 (see below) byte
     645           0 :     aTab[ 67] = new Ww1SingleSprm4State(DUMPNAME("sprmCFVanish")); //  67 chp.fVanish 0,1, 128, or 129 (see below) byte
     646           0 :     aTab[ 68] = new Ww1SingleSprmWord(DUMPNAME("sprmCFtc")); //  68 chp.ftc ftc word
     647           0 :     aTab[ 69] = new Ww1SingleSprmByte(DUMPNAME("sprmCKul")); //  69 chp.kul kul byte
     648           0 :     aTab[ 70] = new Ww1SingleSprm(3, DUMPNAME("sprmCSizePos")); //  70 chp.hps, chp.hpsPos (see below) 3 bytes
     649           0 :     aTab[ 71] = new Ww1SingleSprmWord(DUMPNAME("sprmCDxaSpace")); //  71 chp.dxaSpace dxa word
     650           0 :     aTab[ 72] = new Ww1SingleSprmWord(DUMPNAME("//")); //  72
     651           0 :     aTab[ 73] = new Ww1SingleSprmByte(DUMPNAME("sprmCIco")); //  73 chp.ico ico byte
     652           0 :     aTab[ 74] = new Ww1SingleSprmByte(DUMPNAME("sprmCHps")); //  74 chp.hps hps !byte!
     653           0 :     aTab[ 75] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsInc")); //  75 chp.hps (see below) byte
     654           0 :     aTab[ 76] = new Ww1SingleSprmWord(DUMPNAME("sprmCHpsPos")); //  76 chp.hpsPos hps !word!
     655           0 :     aTab[ 77] = new Ww1SingleSprmByte(DUMPNAME("sprmCHpsPosAdj")); //  77 chp.hpsPos hps (see below) byte
     656           0 :     aTab[ 78] = new Ww1SingleSprmByteSized(0, DUMPNAME(pUnknown)); //  78 ?chp.fBold, chp.fItalic, chp.fSmallCaps, ...
     657             : 
     658           0 :     aTab[ 94] = new Ww1SingleSprmByte(DUMPNAME("sprmPicBrcl")); //  94 pic.brcl brcl (see PIC structure definition) byte
     659           0 :     aTab[ 95] = new Ww1SingleSprmByteSized(0, DUMPNAME("sprmPicScale")); //  95 pic.mx, pic.my, pic.dxaCropleft,
     660             : 
     661           0 :     aTab[117] = new Ww1SingleSprmByte(DUMPNAME("sprmSBkc")); // 117 sep.bkc bkc byte
     662           0 :     aTab[118] = new Ww1SingleSprmBool(DUMPNAME("sprmSFTitlePage")); // 118 sep.fTitlePage 0 or 1 byte
     663           0 :     aTab[119] = new Ww1SingleSprmSColumns(DUMPNAME("sprmSCcolumns")); // 119 sep.ccolM1 # of cols - 1 word
     664           0 :     aTab[120] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaColumns")); // 120 sep.dxaColumns dxa word
     665             : 
     666           0 :     aTab[122] = new Ww1SingleSprmByte(DUMPNAME("sprmSNfcPgn")); // 122 sep.nfcPgn nfc byte
     667             : 
     668           0 :     aTab[125] = new Ww1SingleSprmBool(DUMPNAME("sprmSFPgnRestart")); // 125 sep.fPgnRestart 0 or 1 byte
     669           0 :     aTab[126] = new Ww1SingleSprmBool(DUMPNAME("sprmSFEndnote")); // 126 sep.fEndnote 0 or 1 byte
     670           0 :     aTab[127] = new Ww1SingleSprmByte(DUMPNAME("sprmSLnc")); // 127 sep.lnc lnc byte
     671           0 :     aTab[128] = new Ww1SingleSprmSGprfIhdt(DUMPNAME("sprmSGprfIhdt")); // 128 sep.grpfIhdt grpfihdt (see Headers and Footers topic) byte
     672           0 :     aTab[129] = new Ww1SingleSprmWord(DUMPNAME("sprmSNLnnMod")); // 129 sep.nLnnMod non-neg int. word
     673           0 :     aTab[130] = new Ww1SingleSprmWord(DUMPNAME("sprmSDxaLnn")); // 130 sep.dxaLnn dxa word
     674           0 :     aTab[131] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrTop")); // 131 sep.dyaHdrTop dya word
     675           0 :     aTab[132] = new Ww1SingleSprmWord(DUMPNAME("sprmSDyaHdrBottom")); // 132 sep.dyaHdrBottom dya word
     676           0 :     aTab[133] = new Ww1SingleSprmBool(DUMPNAME("sprmSLBetween")); // 133 sep.fLBetween 0 or 1 byte
     677           0 :     aTab[134] = new Ww1SingleSprmByte(DUMPNAME("sprmSVjc")); // 134 sep.vjc vjc byte
     678           0 :     aTab[135] = new Ww1SingleSprmWord(DUMPNAME("sprmSLnnMin")); // 135 sep.lnnMin lnn word
     679           0 :     aTab[136] = new Ww1SingleSprmWord(DUMPNAME("sprmSPgnStart")); // 136 sep.pgnStart pgn word
     680             : 
     681           0 :     aTab[146] = new Ww1SingleSprmWord(DUMPNAME("sprmTJc")); // 146 tap.jc jc word (low order byte is significant)
     682           0 :     aTab[147] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaLeft")); // 147 tap.rgdxaCenter (see below) dxa word
     683           0 :     aTab[148] = new Ww1SingleSprmWord(DUMPNAME("sprmTDxaGapHalf")); // 148 tap.dxaGapHalf, tap.rgdxaCenter (see below) dxa word
     684             : 
     685           0 :     aTab[152] = new Ww1SingleSprmTDefTable10(DUMPNAME("sprmTDefTable10")); // 152 tap.rgdxaCenter, tap.rgtc complex (see below) variable length
     686           0 :     aTab[153] = new Ww1SingleSprmWord(DUMPNAME("sprmTDyaRowHeight")); // 153 tap.dyaRowHeight dya word
     687             : 
     688           0 :     aTab[158] = new Ww1SingleSprm(4, DUMPNAME("sprmTInsert")); // 158 tap.rgdxaCenter,tap.rgtc complex (see below) 4 bytes
     689           0 :     aTab[159] = new Ww1SingleSprmWord(DUMPNAME("sprmTDelete")); // 159 tap.rgdxaCenter, tap.rgtc complex (see below) word
     690           0 :     aTab[160] = new Ww1SingleSprm(4, DUMPNAME("sprmTDxaCol")); // 160 tap.rgdxaCenter complex (see below) 4 bytes
     691           0 :     aTab[161] = new Ww1SingleSprmWord(DUMPNAME("sprmTMerge")); // 161 tap.fFirstMerged, tap.fMerged complex (see below) word
     692           0 :     aTab[162] = new Ww1SingleSprmWord(DUMPNAME("sprmTSplit")); // 162 tap.fFirstMerged, tap.fMerged complex (see below) word
     693           0 :     aTab[163] = new Ww1SingleSprm(5, DUMPNAME("sprmTSetBrc10")); // 163 tap.rgtc[].rgbrc complex (see below) 5 bytes
     694           0 : }
     695             : 
     696             : // SprmPapx
     697           0 : Ww1SprmPapx::Ww1SprmPapx(sal_uInt8* pByte, sal_uInt16 nSize) :
     698           0 :     Ww1Sprm(Sprm(pByte, nSize), SprmSize(pByte, nSize))
     699             : {
     700           0 :     memset(&aPapx, 0, sizeof(aPapx));
     701           0 :     memcpy(&aPapx, pByte, nSize<sizeof(aPapx)?nSize:sizeof(aPapx));
     702           0 : }
     703             : 
     704           0 : sal_uInt16 Ww1SprmPapx::SprmSize(sal_uInt8*, sal_uInt16 nSize)
     705             : {
     706           0 :     sal_uInt16 nRet = 0;
     707           0 :     if (nSize >= sizeof(W1_PAPX))
     708           0 :         nRet = nSize - ( sizeof(W1_PAPX) - 1 ); // the 1st SprmByte is contained
     709             :                                                 // in the W1_PAPX
     710           0 :     return nRet;
     711             : }
     712             : 
     713           0 : sal_uInt8* Ww1SprmPapx::Sprm(sal_uInt8* pByte, sal_uInt16 nSize)
     714             : {
     715           0 :     sal_uInt8* pRet = NULL;
     716           0 :     if (nSize >= sizeof(W1_PAPX))
     717           0 :         pRet = ((W1_PAPX*)(pByte))->grpprlGet();
     718           0 :     return pRet;
     719             : }
     720             : 
     721             : // Plc
     722           0 : Ww1Plc::Ww1Plc(Ww1Fib& rInFib, sal_uLong ulFilePos, sal_uInt16 nInCountBytes,
     723             :     sal_uInt16 nInItemSize)
     724             :     : p(0), nCountBytes(nInCountBytes), iMac(0), nItemSize(nInItemSize),
     725           0 :     bOK(false), rFib(rInFib)
     726             : {
     727           0 :     if (!nCountBytes)
     728           0 :         bOK = true;
     729             :     else
     730             :     {
     731           0 :         if (rFib.GetStream().Seek(ulFilePos) == (sal_uLong)ulFilePos)
     732             :         {
     733           0 :             if ((p = new sal_uInt8[nCountBytes]) != NULL)
     734             :             {
     735           0 :                 if (rFib.GetStream().Read(p, nCountBytes) == (sal_uLong)nCountBytes)
     736             :                 {
     737           0 :                     bOK = true;
     738           0 :                     iMac = (nCountBytes -
     739           0 :                         sizeof(SVBT32)) / (sizeof(SVBT32) + nItemSize);
     740             :                     OSL_ENSURE(iMac * ((sal_uInt16)sizeof(sal_uLong) + nItemSize) +
     741             :                      (sal_uInt16)sizeof(SVBT32) == nCountBytes, "Ww1Plc");
     742             :                 }
     743             :             }
     744             :         }
     745             :     }
     746           0 : }
     747             : 
     748           0 : Ww1Plc::~Ww1Plc()
     749             : {
     750           0 :     delete p;
     751           0 : }
     752             : 
     753           0 : void Ww1Plc::Seek(sal_uLong ulSeek, sal_uInt16& nIndex)
     754             : {
     755           0 :     if (iMac)
     756           0 :         for (;nIndex <= iMac && Where(nIndex) < ulSeek;nIndex++)
     757             :             ;
     758           0 : }
     759             : 
     760           0 : sal_uLong Ww1Plc::Where(sal_uInt16 nIndex)
     761             : {
     762           0 :     sal_uLong ulRet = 0xffffffff;
     763             :     OSL_ENSURE(nIndex <= iMac, "index out of bounds");
     764           0 :     if (iMac && nIndex <= iMac)
     765           0 :         ulRet = SVBT32ToUInt32(p + sizeof(SVBT32) * nIndex);
     766           0 :     return ulRet;
     767             : }
     768             : 
     769           0 : sal_uInt8* Ww1Plc::GetData(sal_uInt16 nIndex)
     770             : {
     771           0 :     sal_uInt8* pRet = NULL;
     772             :     OSL_ENSURE(nIndex < iMac, "index out of bounds");
     773           0 :     if (nIndex < iMac)
     774           0 :         pRet = p + (iMac + 1) * sizeof(SVBT32) +
     775           0 :          nIndex * nItemSize; // Pointer to content array
     776           0 :     return pRet;
     777             : }
     778             : 
     779             : // PlcBookmarks
     780             : // class Ww1StringList reads a number of P strings from the stream into memory
     781             : // and patches them into C strings
     782             : // nMax returns the count
     783             : // Index 0 references all strings; index 1 and higher reference individual strings
     784           0 : Ww1StringList::Ww1StringList( SvStream& rSt, sal_uLong nFc, sal_uInt16 nCb )
     785           0 :     : pIdxA(0), nMax(0)
     786             : {
     787           0 :     if( nCb > 2 )            // any entries at all?
     788             :     {
     789             :         SVBT16 nCountBytes;
     790             :         OSL_ENSURE(nCb > sizeof(nCountBytes), "Ww1StringList");
     791           0 :         if (rSt.Seek(nFc) == (sal_uLong)nFc)
     792           0 :             if (rSt.Read(nCountBytes, sizeof(nCountBytes))
     793             :                      == sizeof(nCountBytes)) // length again
     794             :             {
     795             :                 OSL_ENSURE(SVBT16ToShort(nCountBytes)
     796             :                          == nCb, "redundant-size missmatch");
     797             :                                     // let's hope that they are always equal
     798           0 :                 sal_Char* pA = new sal_Char[nCb - sizeof(nCountBytes) + 1];
     799             :                                     // allocating PString array
     800             :                 //~ Ww1: new-NULL
     801           0 :                 if (rSt.Read(pA, nCb - sizeof(nCountBytes))
     802           0 :                         == (sal_uLong)nCb - sizeof(nCountBytes))    // read all
     803             :                 {}// do nothing
     804             :                                     // Count number of fonts
     805           0 :                 long nLeft = nCb - sizeof(nCountBytes);
     806           0 :                 sal_Char* p = pA;
     807             :                 while (true)
     808             :                 {
     809             :                     sal_uInt16 nNextSiz;
     810           0 :                     nNextSiz = *p + 1;
     811           0 :                     if(nNextSiz > nLeft)
     812           0 :                         break;
     813           0 :                     nMax++;
     814           0 :                     nLeft -= nNextSiz;
     815           0 :                     if(nLeft < 1)           // need to be able to read next length
     816           0 :                         break;
     817           0 :                     p = p + nNextSiz;
     818             :                 }
     819           0 :                 if (nMax)
     820             :                 {
     821           0 :                     pIdxA = new sal_Char*[nMax+1];      // allocate index array
     822           0 :                     pIdxA[0] = pA;                      // Index 0 : everything
     823             :                                                         // from index 1 C strings
     824           0 :                     pIdxA[1] = pA + 1;                  // fill index array
     825           0 :                     sal_uInt16 i = 2;
     826           0 :                     p = pA;
     827           0 :                     sal_uInt8 nL = *p;
     828             :                     while(true)
     829             :                     {
     830           0 :                         p += nL + 1;                    // new length byte
     831           0 :                         nL = *p;                        // remember length
     832           0 :                         *p = '\0';                      // make C string
     833           0 :                         if( i > nMax )
     834           0 :                             break;
     835           0 :                         pIdxA[i] = p + 1;               // Ptr to C string
     836           0 :                         i++;
     837           0 :                     }
     838             :                 }
     839             :                 else
     840           0 :                     pIdxA = 0;  // No entries -> no array
     841             :             }
     842             :     }
     843           0 : }
     844             : 
     845           0 : const OUString Ww1StringList::GetStr( sal_uInt16 nNum ) const
     846             : {
     847           0 :     OUString sRet;
     848           0 :     if( nNum <= nMax )
     849           0 :         sRet = OUString( pIdxA[ nNum+1 ], strlen(pIdxA[ nNum+1 ]), RTL_TEXTENCODING_MS_1252 );
     850           0 :     return sRet;
     851             : }
     852             : 
     853           0 : Ww1Bookmarks::Ww1Bookmarks(Ww1Fib& rInFib)
     854           0 :     : aNames(rInFib), rFib(rInFib), nIsEnd(0)
     855             : {
     856           0 :     pPos[0] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbkfGet(),
     857           0 :                                     rFib.GetFIB().cbPlcfbkfGet(), sal_False);
     858           0 :     nPlcIdx[0] = 0;
     859           0 :     pPos[1] = new Ww1PlcBookmarkPos(rFib, rFib.GetFIB().fcPlcfbklGet(),
     860           0 :                                     rFib.GetFIB().cbPlcfbklGet(), sal_True);
     861           0 :     nPlcIdx[1] = 0;
     862           0 :     bOK = !aNames.GetError() && !pPos[0]->GetError() && !pPos[1]->GetError();
     863           0 : }
     864             : 
     865             : // There's one twist to this operator++: in the case of 2 adjacent bookmarks,
     866             : // the end of the first one should be reached first, and then the start of the
     867             : // second one. However, if there are 2 bookmarks of length 0 on top of each
     868             : // other, each bookmarks' respective start *must* be found before its end.
     869             : // The case: ][
     870             : //            [...]
     871             : //           ][
     872             : // is not solved yet. I'd need to jump back and forth in the start and end
     873             : // indices, using another index or a bitfield or something similar for keeping
     874             : // track of already processed bookmarks.
     875           0 : void Ww1Bookmarks::operator++()
     876             : {
     877           0 :     if( bOK )
     878             :     {
     879           0 :         nPlcIdx[nIsEnd]++;
     880             : 
     881           0 :         sal_uLong l0 = pPos[0]->Where(nPlcIdx[0]);
     882           0 :         sal_uLong l1 = pPos[1]->Where(nPlcIdx[1]);
     883           0 :         if( l0 < l1 )
     884           0 :             nIsEnd = 0;
     885           0 :         else if( l1 < l0 )
     886           0 :             nIsEnd = 1;
     887             :         else
     888           0 :             nIsEnd = ( nIsEnd ) ? 0 : 1;
     889             :     }
     890           0 : }
     891             : 
     892           0 : long Ww1Bookmarks::GetHandle() const
     893             : {
     894           0 :     if( bOK )
     895             :     {
     896           0 :         if( nIsEnd )
     897           0 :             return nPlcIdx[1];
     898             : 
     899           0 :         const sal_uInt8* p = pPos[0]->GetData( nPlcIdx[0] );
     900           0 :         if( p )
     901           0 :             return SVBT16ToShort( p );
     902             :     }
     903           0 :     return LONG_MAX;
     904             : }
     905             : 
     906           0 : long Ww1Bookmarks::Len() const
     907             : {
     908           0 :     if( nIsEnd )
     909             :     {
     910             :         OSL_ENSURE( false, "Invalid usage (1) of Ww1Bookmarks::Len()" );
     911           0 :         return 0;
     912             :     }
     913           0 :     sal_uInt16 nEndIdx = SVBT16ToShort(pPos[0]->GetData(nPlcIdx[0]));
     914           0 :     return pPos[1]->Where(nEndIdx) - pPos[0]->Where(nPlcIdx[0]);
     915             : }
     916             : 
     917           0 : const OUString Ww1Bookmarks::GetName() const
     918             : {
     919           0 :     if( nIsEnd )
     920           0 :         return OUString("???");
     921           0 :     return aNames.GetStr( nPlcIdx[0] );
     922             : }
     923             : 
     924             : // Fkp
     925           0 : Ww1Fkp::Ww1Fkp(SvStream& rStream, sal_uLong ulFilePos, sal_uInt16 _nItemSize) :
     926             :     nItemSize(_nItemSize),
     927           0 :     bOK(sal_False)
     928             : {
     929           0 :     if (rStream.Seek(ulFilePos) == (sal_uLong)ulFilePos)
     930           0 :         if (rStream.Read(aFkp, sizeof(aFkp)) == sizeof(aFkp))
     931           0 :             bOK = sal_True;
     932           0 : }
     933             : 
     934           0 : sal_uLong Ww1Fkp::Where(sal_uInt16 nIndex)
     935             : {
     936           0 :     sal_uLong lRet = 0xffffffff;
     937             :     OSL_ENSURE(nIndex<=Count(), "index out of bounds");
     938           0 :     if (nIndex<=Count())
     939           0 :         lRet = SVBT32ToUInt32(aFkp+nIndex*sizeof(SVBT32));
     940           0 :     return lRet;
     941             : }
     942             : 
     943           0 : sal_uInt8* Ww1Fkp::GetData(sal_uInt16 nIndex)
     944             : {
     945           0 :     sal_uInt8* pRet = NULL;
     946             :     OSL_ENSURE(nIndex<=Count(), "index out of bounds");
     947           0 :     if (nIndex<=Count())
     948           0 :         pRet = aFkp + (Count()+1) * sizeof(SVBT32) +
     949           0 :          nIndex * nItemSize; // start of the structures
     950           0 :     return pRet;
     951             : }
     952             : 
     953             : // FkpPap
     954           0 : sal_Bool Ww1FkpPap::Fill(sal_uInt16 nIndex, sal_uInt8*& p, sal_uInt16& rnCountBytes)
     955             : {
     956             :     OSL_ENSURE( nIndex < Count(), "Ww1FkpPap::Fill() Index out of Range" );
     957           0 :     sal_uInt16 nOffset = *GetData(nIndex) * 2;
     958           0 :     if (nOffset)
     959             :     {
     960             :         OSL_ENSURE(nOffset>(sal_uInt16)(Count()*sizeof(SVBT32)), "calc error");
     961           0 :         rnCountBytes = *(aFkp+nOffset) * 2;
     962           0 :         nOffset += sizeof(sal_uInt8);
     963           0 :         if( nOffset + rnCountBytes < 511 )  // SH: Assert triggered 1 too early
     964           0 :             rnCountBytes++;                 // SH: I'm not entirely sure if the last
     965             :                                             // byte of the PAPX is used, but this way
     966             :                                             // we don't forget any and are on the
     967             :                                             // safe side either way
     968             :         OSL_ENSURE(nOffset+rnCountBytes <= 511, "calc error");
     969           0 :         p = aFkp + nOffset;
     970             :     }
     971             :     else
     972             :     {
     973           0 :         p = NULL;
     974           0 :         rnCountBytes = 0;
     975             :     }
     976           0 :     return sal_True;
     977             : }
     978             : 
     979             : // FkpChp
     980           0 : sal_Bool Ww1FkpChp::Fill(sal_uInt16 nIndex, W1_CHP& aChp)
     981             : {
     982             :     OSL_ENSURE( nIndex < Count(), "Ww1FkpChp::Fill() Index out of Range" );
     983           0 :     memset(&aChp, 0, sizeof(aChp));
     984           0 :     sal_uInt16 nOffset = GetData(nIndex)[0] * 2;
     985           0 :     if (nOffset)
     986             :     {
     987             :         OSL_ENSURE(nOffset>(sal_uInt16)(Count()*sizeof(SVBT32)), "calc error");
     988           0 :         sal_uInt16 nCountBytes = aFkp[nOffset];
     989           0 :         nOffset += sizeof(sal_uInt8);
     990             :         OSL_ENSURE(nCountBytes <= 511-nOffset, "calc error");
     991             :         OSL_ENSURE(nCountBytes <= sizeof(aChp), "calc error");
     992           0 :         memcpy(&aChp, aFkp+nOffset, nCountBytes);
     993             :     }
     994           0 :     return sal_True;
     995             : }
     996             : 
     997             : // Assoc
     998           0 : Ww1Assoc::Ww1Assoc(Ww1Fib& _rFib)
     999           0 :     : rFib(_rFib), pBuffer(NULL), bOK(sal_False)
    1000             : {
    1001           0 :     sal_uInt16 cb = rFib.GetFIB().cbSttbfAssocGet();
    1002             :     sal_uInt16 i;
    1003             : 
    1004           0 :     for ( i = 0; i < MaxFields; i++ )
    1005           0 :         pStrTbl[i] = NULL;
    1006           0 :     if ((pBuffer = new sal_Char[cb]) != NULL
    1007           0 :      && rFib.GetStream().Seek(rFib.GetFIB().fcSttbfAssocGet()) ==
    1008           0 :         rFib.GetFIB().fcSttbfAssocGet()
    1009           0 :      && rFib.GetStream().Read(pBuffer, cb) == cb)
    1010             :     {
    1011             :         sal_uInt16 j;
    1012             :         OSL_ENSURE( cb == SVBT16ToShort( *(SVBT16*)pBuffer ), "size mismatch");
    1013           0 :         for (i=0,j=sizeof(SVBT16);j<cb && i<Criteria1;i++)
    1014             :         {
    1015           0 :             pStrTbl[i] = pBuffer+j;
    1016           0 :             j += (*pBuffer + j) + 1;
    1017             :         }
    1018           0 :         bOK = sal_True;
    1019             :     }
    1020           0 : }
    1021             : 
    1022           0 : OUString Ww1Assoc::GetStr(sal_uInt16 code)
    1023             : {
    1024           0 :     OStringBuffer sRet;
    1025             :     OSL_ENSURE(code<MaxFields, "out of range");
    1026           0 :     if (pStrTbl[code] != NULL)
    1027           0 :         for( sal_uInt16 i=0;i<pStrTbl[code][0];i++ )
    1028           0 :             sRet.append(pStrTbl[code][i+1]);
    1029             :     return OStringToOUString(sRet.makeStringAndClear(),
    1030           0 :         RTL_TEXTENCODING_MS_1252);
    1031             : }
    1032             : 
    1033             : // Pap
    1034           0 : Ww1Pap::Ww1Pap(Ww1Fib& _rFib)
    1035             :     : Ww1PlcPap(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0),
    1036           0 :     nPushedFkpIndex(0xffff), ulOffset(0), pPap(0)
    1037             : {
    1038           0 : }
    1039             : 
    1040           0 : void Ww1Pap::Seek(sal_uLong ulSeek)
    1041             : {
    1042           0 :     while (ulSeek > Where())
    1043           0 :         ++(*this);
    1044           0 : }
    1045             : 
    1046             : // SH: Where has been passed a parameter which determines if the index should be set
    1047             : // to 0 upon constructing a new Fkp (must not happen for Push/Pop)
    1048             : // Can't think of an elegant way for now
    1049           0 : sal_uLong Ww1Pap::Where( sal_Bool bSetIndex )
    1050             : {
    1051           0 :     sal_uLong ulRet = 0xffffffff;
    1052           0 :     if (pPap == NULL)
    1053           0 :         if (nPlcIndex < Count())
    1054             :         {
    1055           0 :             pPap = new Ww1FkpPap(rFib.GetStream(),
    1056           0 :                         SVBT16ToShort(GetData(nPlcIndex)) << 9);
    1057           0 :             if( bSetIndex )
    1058           0 :                 nFkpIndex = 0;
    1059             :         }
    1060           0 :     if (pPap != NULL)
    1061           0 :         if (nFkpIndex <= pPap->Count())
    1062           0 :             ulRet = pPap->Where(nFkpIndex) - rFib.GetFIB().fcMinGet();
    1063           0 :     return ulRet;
    1064             : }
    1065             : 
    1066           0 : void Ww1Pap::operator++()
    1067             : {
    1068           0 :     if (pPap != NULL)
    1069           0 :         if (++nFkpIndex > pPap->Count())
    1070             :         {
    1071           0 :             delete pPap;
    1072           0 :             pPap = NULL;
    1073           0 :             nPlcIndex++;
    1074             :         }
    1075           0 : }
    1076             : 
    1077             : // SH: FindSprm looks for Sprm nId in grpprl
    1078             : // Return value: pointer or 0
    1079           0 : sal_Bool Ww1Pap::FindSprm(sal_uInt16 nId, sal_uInt8* pStart, sal_uInt8* pEnd)
    1080             : {
    1081           0 :     Ww1Sprm aSprm( pStart, static_cast< sal_uInt16 >(pEnd-pStart) );
    1082           0 :     sal_uInt16 nC = aSprm.Count();
    1083             :     sal_uInt16 i;
    1084             :     sal_uInt8 nI;
    1085             :     sal_uInt16 nLen;
    1086             :     sal_uInt8 *pData;
    1087           0 :     for( i = 0; i < nC; i++ ){
    1088           0 :         aSprm.Fill( i, nI, nLen, pData );
    1089           0 :         if( nI == nId )
    1090           0 :             return sal_True;
    1091             :     }
    1092           0 :     return sal_False;
    1093             : }
    1094             : 
    1095           0 : sal_Bool Ww1Pap::HasId0(sal_uInt16 nId)
    1096             : {
    1097           0 :     sal_Bool bRet = sal_False;
    1098           0 :     UpdateIdx();
    1099             : 
    1100           0 :     if( !pPap ){
    1101             :         OSL_ENSURE( false, "Ww1Pap::HasId():: cannot create a pPap" );
    1102           0 :         return sal_False;
    1103             :     }
    1104             : 
    1105             :     sal_uInt8* pByte;
    1106             :     sal_uInt16 n;
    1107           0 :     if( pPap->Fill(nFkpIndex, pByte, n) ){
    1108           0 :         sal_uInt8* p2 = ((W1_PAPX*)(pByte))->grpprlGet(); // SH: Offset was missing
    1109           0 :         bRet = FindSprm( nId, p2, pByte + n );
    1110             :     }
    1111           0 :     return bRet;
    1112             : }
    1113             : 
    1114           0 : sal_Bool Ww1Pap::HasId(sal_uInt16 nId)
    1115             : {
    1116           0 :     sal_uInt16 nPushedPlcIndex2 = nPlcIndex;
    1117           0 :     sal_uInt16 nPushedFkpIndex2 = nFkpIndex;
    1118           0 :     sal_Bool bRet = HasId0( nId );
    1119           0 :     if (nPlcIndex != nPushedPlcIndex2)
    1120             :     {
    1121           0 :         delete pPap;
    1122           0 :         pPap = NULL;
    1123             :     }
    1124           0 :     nPlcIndex = nPushedPlcIndex2;
    1125           0 :     nFkpIndex = nPushedFkpIndex2;
    1126           0 :     Where( sal_False );
    1127           0 :     return bRet;
    1128             : }
    1129             : 
    1130             : // Chp
    1131           0 : Ww1Chp::Ww1Chp(Ww1Fib& _rFib)
    1132             :     : Ww1PlcChp(_rFib), nPlcIndex(0), nPushedPlcIndex(0xffff), nFkpIndex(0),
    1133           0 :     nPushedFkpIndex(0xffff), ulOffset(0), pChp(0)
    1134             : {
    1135           0 : }
    1136             : 
    1137           0 : void Ww1Chp::Seek(sal_uLong ulSeek)
    1138             : {
    1139           0 :     while (ulSeek > Where())
    1140           0 :         ++(*this);
    1141           0 : }
    1142             : 
    1143             : // SH: Where has been passed a parameter which determines if the index should be set
    1144             : // to 0 upon constructing a new Fkp (must not happen for Push/Pop)
    1145             : // Can't think of an elegant way for now
    1146           0 : sal_uLong Ww1Chp::Where( sal_Bool bSetIndex )
    1147             : {
    1148           0 :     sal_uLong ulRet = 0xffffffff;
    1149           0 :     if (pChp == NULL)
    1150           0 :         if (nPlcIndex < Count())
    1151             :         {
    1152           0 :             pChp = new Ww1FkpChp(rFib.GetStream(),
    1153           0 :                         SVBT16ToShort(GetData(nPlcIndex)) << 9);
    1154           0 :             if( bSetIndex )
    1155           0 :                 nFkpIndex = 0;
    1156             :         }
    1157           0 :     if (pChp != NULL)
    1158           0 :         if (nFkpIndex <= pChp->Count())
    1159           0 :             ulRet = pChp->Where(nFkpIndex) -
    1160           0 :                      rFib.GetFIB().fcMinGet() - ulOffset;
    1161           0 :     return ulRet;
    1162             : }
    1163             : 
    1164           0 : void Ww1Chp::operator++()
    1165             : {
    1166           0 :     if (pChp != NULL)
    1167           0 :         if (++nFkpIndex > pChp->Count())
    1168             :         {
    1169           0 :             delete pChp;
    1170           0 :             pChp = NULL;
    1171           0 :             nPlcIndex++;
    1172             :         }
    1173           0 : }
    1174             : 
    1175             : // Manager
    1176           0 : Ww1Manager::Ww1Manager(SvStream& rStrm, sal_uLong nFieldFlgs)
    1177             :     : bOK(sal_False), bInTtp(false), bInStyle(false), bStopAll(false), aFib(rStrm),
    1178             :     aDop(aFib), aFonts(aFib, nFieldFlgs), aDoc(aFib), pDoc(&aDoc),
    1179             :     ulDocSeek(0), pSeek(&ulDocSeek), aFld(aFib), pFld(&aFld), aChp(aFib),
    1180             :     aPap(aFib), aFtn(aFib), aBooks(aFib),
    1181           0 :     aSep(aFib, aDop.GetDOP().grpfIhdtGet())
    1182             : {
    1183           0 :     bOK =  !aFib.GetError()
    1184           0 :         && !aFib.GetFIB().fComplexGet()
    1185           0 :         && !aDoc.GetError()
    1186           0 :         && !aSep.GetError()
    1187           0 :         && !aPap.GetError()
    1188           0 :         && !aChp.GetError()
    1189           0 :         && !aFld.GetError()
    1190           0 :         && !aFtn.GetError()
    1191           0 :         && !aBooks.GetError();
    1192           0 : }
    1193             : 
    1194           0 : sal_Bool Ww1Manager::HasInTable()
    1195             : {
    1196           0 :     return aPap.HasId(24); // Ww1SingleSprmPFInTable
    1197             : }
    1198             : 
    1199           0 : sal_Bool Ww1Manager::HasTtp()
    1200             : {
    1201           0 :     return aPap.HasId(25); // Ww1SingleSprmPTtp
    1202             : }
    1203             : 
    1204           0 : sal_Bool Ww1Manager::HasPPc()
    1205             : {
    1206           0 :     return aPap.HasId(29); // Ww1SingleSprmPPc
    1207             : }
    1208             : 
    1209           0 : sal_Bool Ww1Manager::HasPDxaAbs()
    1210             : {
    1211           0 :     return aPap.HasId(26); // Ww1SingleSprmPDxaAbs
    1212             : }
    1213             : 
    1214             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10