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