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: */
|