File: | home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx |
Warning: | line 1994, column 12 Array access (from variable 'pData') results in a null pointer dereference |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <memory> | ||||||
21 | #include "ww8scan.hxx" | ||||||
22 | #include "ww8par.hxx" | ||||||
23 | |||||||
24 | #include <cassert> | ||||||
25 | #include <cstddef> | ||||||
26 | #include <cstring> | ||||||
27 | #include <algorithm> | ||||||
28 | |||||||
29 | #include <i18nlangtag/mslangid.hxx> | ||||||
30 | #include "sprmids.hxx" | ||||||
31 | #include <rtl/tencinfo.h> | ||||||
32 | #include <sal/macros.h> | ||||||
33 | #include <sal/log.hxx> | ||||||
34 | |||||||
35 | #include <swerror.h> | ||||||
36 | |||||||
37 | #include <comphelper/string.hxx> | ||||||
38 | #include <unotools/localedatawrapper.hxx> | ||||||
39 | #include <i18nlangtag/lang.h> | ||||||
40 | #include <o3tl/safeint.hxx> | ||||||
41 | #include <tools/stream.hxx> | ||||||
42 | |||||||
43 | #include <vcl/settings.hxx> | ||||||
44 | #include <vcl/svapp.hxx> | ||||||
45 | |||||||
46 | #ifdef DEBUGSPRMREADER | ||||||
47 | #include <stdio.h> | ||||||
48 | #endif | ||||||
49 | |||||||
50 | using namespace ::com::sun::star::lang; | ||||||
51 | |||||||
52 | namespace | ||||||
53 | { | ||||||
54 | /** | ||||||
55 | winword strings are typically Belt and Braces strings preceded with a | ||||||
56 | pascal style count, and ending with a c style 0 terminator. 16bit chars | ||||||
57 | and count for ww8+ and 8bit chars and count for ww7-. The count and 0 | ||||||
58 | can be checked for integrity to catch errors (e.g. lotus created | ||||||
59 | documents) where in error 8bit strings are used instead of 16bits | ||||||
60 | strings for style names. | ||||||
61 | */ | ||||||
62 | bool TestBeltAndBraces(SvStream& rStrm) | ||||||
63 | { | ||||||
64 | bool bRet = false; | ||||||
65 | sal_uInt32 nOldPos = rStrm.Tell(); | ||||||
66 | sal_uInt16 nBelt(0); | ||||||
67 | rStrm.ReadUInt16( nBelt ); | ||||||
68 | nBelt *= sizeof(sal_Unicode); | ||||||
69 | if (rStrm.good() && (rStrm.remainingSize() >= (nBelt + sizeof(sal_Unicode)))) | ||||||
70 | { | ||||||
71 | rStrm.SeekRel(nBelt); | ||||||
72 | if (rStrm.good()) | ||||||
73 | { | ||||||
74 | sal_Unicode cBraces(0); | ||||||
75 | rStrm.ReadUtf16( cBraces ); | ||||||
76 | if (rStrm.good() && cBraces == 0) | ||||||
77 | bRet = true; | ||||||
78 | } | ||||||
79 | } | ||||||
80 | rStrm.Seek(nOldPos); | ||||||
81 | return bRet; | ||||||
82 | } | ||||||
83 | } | ||||||
84 | |||||||
85 | const wwSprmSearcher *wwSprmParser::GetWW2SprmSearcher() | ||||||
86 | { | ||||||
87 | //double lock me | ||||||
88 | // WW2 Sprms | ||||||
89 | static const SprmInfoRow aSprms[] = | ||||||
90 | { | ||||||
91 | { 0, { 0, L_FIX} }, // "Default-sprm", will be skipped | ||||||
92 | { 2, { 1, L_FIX} }, // "sprmPIstd", pap.istd (style code) | ||||||
93 | { 3, { 0, L_VAR} }, // "sprmPIstdPermute pap.istd permutation | ||||||
94 | { 4, { 1, L_FIX} }, // "sprmPIncLv1" pap.istddifference | ||||||
95 | { 5, { 1, L_FIX} }, // "sprmPJc" pap.jc (justification) | ||||||
96 | { 6, { 1, L_FIX} }, // "sprmPFSideBySide" pap.fSideBySide | ||||||
97 | { 7, { 1, L_FIX} }, // "sprmPFKeep" pap.fKeep | ||||||
98 | { 8, { 1, L_FIX} }, // "sprmPFKeepFollow " pap.fKeepFollow | ||||||
99 | { 9, { 1, L_FIX} }, // "sprmPPageBreakBefore" pap.fPageBreakBefore | ||||||
100 | { 10, { 1, L_FIX} }, // "sprmPBrcl" pap.brcl | ||||||
101 | { 11, { 1, L_FIX} }, // "sprmPBrcp" pap.brcp | ||||||
102 | { 12, { 1, L_FIX} }, // "sprmPNfcSeqNumb" pap.nfcSeqNumb | ||||||
103 | { 13, { 1, L_FIX} }, // "sprmPNoSeqNumb" pap.nnSeqNumb | ||||||
104 | { 14, { 1, L_FIX} }, // "sprmPFNoLineNumb" pap.fNoLnn | ||||||
105 | { 15, { 0, L_VAR} }, // "?sprmPChgTabsPapx" pap.itbdMac, ... | ||||||
106 | { 16, { 2, L_FIX} }, // "sprmPDxaRight" pap.dxaRight | ||||||
107 | { 17, { 2, L_FIX} }, // "sprmPDxaLeft" pap.dxaLeft | ||||||
108 | { 18, { 2, L_FIX} }, // "sprmPNest" pap.dxaLeft | ||||||
109 | { 19, { 2, L_FIX} }, // "sprmPDxaLeft1" pap.dxaLeft1 | ||||||
110 | { 20, { 2, L_FIX} }, // "sprmPDyaLine" pap.lspd an LSPD | ||||||
111 | { 21, { 2, L_FIX} }, // "sprmPDyaBefore" pap.dyaBefore | ||||||
112 | { 22, { 2, L_FIX} }, // "sprmPDyaAfter" pap.dyaAfter | ||||||
113 | { 23, { 0, L_VAR} }, // "?sprmPChgTabs" pap.itbdMac, pap.rgdxaTab, ... | ||||||
114 | { 24, { 1, L_FIX} }, // "sprmPFInTable" pap.fInTable | ||||||
115 | { 25, { 1, L_FIX} }, // "sprmPTtp" pap.fTtp | ||||||
116 | { 26, { 2, L_FIX} }, // "sprmPDxaAbs" pap.dxaAbs | ||||||
117 | { 27, { 2, L_FIX} }, // "sprmPDyaAbs" pap.dyaAbs | ||||||
118 | { 28, { 2, L_FIX} }, // "sprmPDxaWidth" pap.dxaWidth | ||||||
119 | { 29, { 1, L_FIX} }, // "sprmPPc" pap.pcHorz, pap.pcVert | ||||||
120 | { 30, { 2, L_FIX} }, // "sprmPBrcTop10" pap.brcTop BRC10 | ||||||
121 | { 31, { 2, L_FIX} }, // "sprmPBrcLeft10" pap.brcLeft BRC10 | ||||||
122 | { 32, { 2, L_FIX} }, // "sprmPBrcBottom10" pap.brcBottom BRC10 | ||||||
123 | { 33, { 2, L_FIX} }, // "sprmPBrcRight10" pap.brcRight BRC10 | ||||||
124 | { 34, { 2, L_FIX} }, // "sprmPBrcBetween10" pap.brcBetween BRC10 | ||||||
125 | { 35, { 2, L_FIX} }, // "sprmPBrcBar10" pap.brcBar BRC10 | ||||||
126 | { 36, { 2, L_FIX} }, // "sprmPFromText10" pap.dxaFromText dxa | ||||||
127 | { 37, { 1, L_FIX} }, // "sprmPWr" pap.wr wr | ||||||
128 | { 38, { 2, L_FIX} }, // "sprmPBrcTop" pap.brcTop BRC | ||||||
129 | { 39, { 2, L_FIX} }, // "sprmPBrcLeft" pap.brcLeft BRC | ||||||
130 | { 40, { 2, L_FIX} }, // "sprmPBrcBottom" pap.brcBottom BRC | ||||||
131 | { 41, { 2, L_FIX} }, // "sprmPBrcRight" pap.brcRight BRC | ||||||
132 | { 42, { 2, L_FIX} }, // "sprmPBrcBetween" pap.brcBetween BRC | ||||||
133 | { 43, { 2, L_FIX} }, // "sprmPBrcBar" pap.brcBar BRC word | ||||||
134 | { 44, { 1, L_FIX} }, // "sprmPFNoAutoHyph" pap.fNoAutoHyph | ||||||
135 | { 45, { 2, L_FIX} }, // "sprmPWHeightAbs" pap.wHeightAbs w | ||||||
136 | { 46, { 2, L_FIX} }, // "sprmPDcs" pap.dcs DCS | ||||||
137 | { 47, { 2, L_FIX} }, // "sprmPShd" pap.shd SHD | ||||||
138 | { 48, { 2, L_FIX} }, // "sprmPDyaFromText" pap.dyaFromText dya | ||||||
139 | { 49, { 2, L_FIX} }, // "sprmPDxaFromText" pap.dxaFromText dxa | ||||||
140 | { 50, { 1, L_FIX} }, // "sprmPFBiDi" pap.fBiDi 0 or 1 byte | ||||||
141 | { 51, { 1, L_FIX} }, // "sprmPFWidowControl" pap.fWidowControl 0 or 1 byte | ||||||
142 | { 52, { 0, L_FIX} }, // "?sprmPRuler 52" | ||||||
143 | { 53, { 1, L_FIX} }, // "sprmCFStrikeRM" chp.fRMarkDel 1 or 0 bit | ||||||
144 | { 54, { 1, L_FIX} }, // "sprmCFRMark" chp.fRMark 1 or 0 bit | ||||||
145 | { 55, { 1, L_FIX} }, // "sprmCFFieldVanish" chp.fFieldVanish 1 or 0 bit | ||||||
146 | { 57, { 0, L_VAR} }, // "sprmCDefault" whole CHP | ||||||
147 | { 58, { 0, L_FIX} }, // "sprmCPlain" whole CHP | ||||||
148 | { 60, { 1, L_FIX} }, // "sprmCFBold" chp.fBold 0,1, 128, or 129 | ||||||
149 | { 61, { 1, L_FIX} }, // "sprmCFItalic" chp.fItalic 0,1, 128, or 129 | ||||||
150 | { 62, { 1, L_FIX} }, // "sprmCFStrike" chp.fStrike 0,1, 128, or 129 | ||||||
151 | { 63, { 1, L_FIX} }, // "sprmCFOutline" chp.fOutline 0,1, 128, or 129 | ||||||
152 | { 64, { 1, L_FIX} }, // "sprmCFShadow" chp.fShadow 0,1, 128, or 129 | ||||||
153 | { 65, { 1, L_FIX} }, // "sprmCFSmallCaps" chp.fSmallCaps 0,1, 128, or 129 | ||||||
154 | { 66, { 1, L_FIX} }, // "sprmCFCaps" chp.fCaps 0,1, 128, or 129 | ||||||
155 | { 67, { 1, L_FIX} }, // "sprmCFVanish" chp.fVanish 0,1, 128, or 129 | ||||||
156 | { 68, { 2, L_FIX} }, // "sprmCFtc" chp.ftc ftc word | ||||||
157 | { 69, { 1, L_FIX} }, // "sprmCKul" chp.kul kul byte | ||||||
158 | { 70, { 3, L_FIX} }, // "sprmCSizePos" chp.hps, chp.hpsPos | ||||||
159 | { 71, { 2, L_FIX} }, // "sprmCDxaSpace" chp.dxaSpace dxa | ||||||
160 | { 72, { 2, L_FIX} }, // "sprmCLid" chp.lid LID | ||||||
161 | { 73, { 1, L_FIX} }, // "sprmCIco" chp.ico ico byte | ||||||
162 | { 74, { 1, L_FIX} }, // "sprmCHps" chp.hps hps !word! | ||||||
163 | { 75, { 1, L_FIX} }, // "sprmCHpsInc" chp.hps | ||||||
164 | { 76, { 1, L_FIX} }, // "sprmCHpsPos" chp.hpsPos hps !word! | ||||||
165 | { 77, { 1, L_FIX} }, // "sprmCHpsPosAdj" chp.hpsPos hps | ||||||
166 | { 78, { 0, L_VAR} }, // "?sprmCMajority" chp.fBold, chp.fItalic, ... | ||||||
167 | { 80, { 1, L_FIX} }, // "sprmCFBoldBi" chp.fBoldBi | ||||||
168 | { 81, { 1, L_FIX} }, // "sprmCFItalicBi" chp.fItalicBi | ||||||
169 | { 82, { 2, L_FIX} }, // "sprmCFtcBi" chp.ftcBi | ||||||
170 | { 83, { 2, L_FIX} }, // "sprmClidBi" chp.lidBi | ||||||
171 | { 84, { 1, L_FIX} }, // "sprmCIcoBi" chp.icoBi | ||||||
172 | { 85, { 1, L_FIX} }, // "sprmCHpsBi" chp.hpsBi | ||||||
173 | { 86, { 1, L_FIX} }, // "sprmCFBiDi" chp.fBiDi | ||||||
174 | { 87, { 1, L_FIX} }, // "sprmCFDiacColor" chp.fDiacUSico | ||||||
175 | { 94, { 1, L_FIX} }, // "sprmPicBrcl" pic.brcl brcl (see PIC definition) | ||||||
176 | { 95, {12, L_VAR} }, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft, | ||||||
177 | { 96, { 2, L_FIX} }, // "sprmPicBrcTop" pic.brcTop BRC word | ||||||
178 | { 97, { 2, L_FIX} }, // "sprmPicBrcLeft" pic.brcLeft BRC word | ||||||
179 | { 98, { 2, L_FIX} }, // "sprmPicBrcBottom" pic.brcBottom BRC word | ||||||
180 | { 99, { 2, L_FIX} }, // "sprmPicBrcRight" pic.brcRight BRC word | ||||||
181 | {112, { 1, L_FIX} }, // "sprmSFRTLGutter", set to one if gutter is on | ||||||
182 | {114, { 1, L_FIX} }, // "sprmSFBiDi" ;;; | ||||||
183 | {115, { 2, L_FIX} }, // "sprmSDmBinFirst" sep.dmBinFirst word | ||||||
184 | {116, { 2, L_FIX} }, // "sprmSDmBinOther" sep.dmBinOther word | ||||||
185 | {117, { 1, L_FIX} }, // "sprmSBkc" sep.bkc bkc byte | ||||||
186 | {118, { 1, L_FIX} }, // "sprmSFTitlePage" sep.fTitlePage 0 or 1 byte | ||||||
187 | {119, { 2, L_FIX} }, // "sprmSCcolumns" sep.ccolM1 # of cols - 1 word | ||||||
188 | {120, { 2, L_FIX} }, // "sprmSDxaColumns" sep.dxaColumns dxa word | ||||||
189 | {121, { 1, L_FIX} }, // "sprmSFAutoPgn" sep.fAutoPgn obsolete byte | ||||||
190 | {122, { 1, L_FIX} }, // "sprmSNfcPgn" sep.nfcPgn nfc byte | ||||||
191 | {123, { 2, L_FIX} }, // "sprmSDyaPgn" sep.dyaPgn dya short | ||||||
192 | {124, { 2, L_FIX} }, // "sprmSDxaPgn" sep.dxaPgn dya short | ||||||
193 | {125, { 1, L_FIX} }, // "sprmSFPgnRestart" sep.fPgnRestart 0 or 1 byte | ||||||
194 | {126, { 1, L_FIX} }, // "sprmSFEndnote" sep.fEndnote 0 or 1 byte | ||||||
195 | {127, { 1, L_FIX} }, // "sprmSLnc" sep.lnc lnc byte | ||||||
196 | {128, { 1, L_FIX} }, // "sprmSGprfIhdt" sep.grpfIhdt grpfihdt | ||||||
197 | {129, { 2, L_FIX} }, // "sprmSNLnnMod" sep.nLnnMod non-neg int. word | ||||||
198 | {130, { 2, L_FIX} }, // "sprmSDxaLnn" sep.dxaLnn dxa word | ||||||
199 | {131, { 2, L_FIX} }, // "sprmSDyaHdrTop" sep.dyaHdrTop dya word | ||||||
200 | {132, { 2, L_FIX} }, // "sprmSDyaHdrBottom" sep.dyaHdrBottom dya word | ||||||
201 | {133, { 1, L_FIX} }, // "sprmSLBetween" sep.fLBetween 0 or 1 byte | ||||||
202 | {134, { 1, L_FIX} }, // "sprmSVjc" sep.vjc vjc byte | ||||||
203 | {135, { 2, L_FIX} }, // "sprmSLnnMin" sep.lnnMin lnn word | ||||||
204 | {136, { 2, L_FIX} }, // "sprmSPgnStart" sep.pgnStart pgn word | ||||||
205 | {137, { 1, L_FIX} }, // "sprmSBOrientation" sep.dmOrientPage dm byte | ||||||
206 | {138, { 1, L_FIX} }, // "sprmSFFacingCol" ;;; | ||||||
207 | {139, { 2, L_FIX} }, // "sprmSXaPage" sep.xaPage xa word | ||||||
208 | {140, { 2, L_FIX} }, // "sprmSYaPage" sep.yaPage ya word | ||||||
209 | {141, { 2, L_FIX} }, // "sprmSDxaLeft" sep.dxaLeft dxa word | ||||||
210 | {142, { 2, L_FIX} }, // "sprmSDxaRight" sep.dxaRight dxa word | ||||||
211 | {143, { 2, L_FIX} }, // "sprmSDyaTop" sep.dyaTop dya word | ||||||
212 | {144, { 2, L_FIX} }, // "sprmSDyaBottom" sep.dyaBottom dya word | ||||||
213 | {145, { 2, L_FIX} }, // "sprmSDzaGutter" sep.dzaGutter dza word | ||||||
214 | {146, { 2, L_FIX} }, // "sprmTJc" tap.jc jc (low order byte is significant) | ||||||
215 | {147, { 2, L_FIX} }, // "sprmTDxaLeft" tap.rgdxaCenter dxa word | ||||||
216 | {148, { 2, L_FIX} }, // "sprmTDxaGapHalf" tap.dxaGapHalf, tap.rgdxaCenter | ||||||
217 | {149, { 1, L_FIX} }, // "sprmTFBiDi" ;;; | ||||||
218 | {152, { 0, L_VAR} }, // "sprmTDefTable10" tap.rgdxaCenter, tap.rgtc complex | ||||||
219 | {153, { 2, L_FIX} }, // "sprmTDyaRowHeight" tap.dyaRowHeight dya word | ||||||
220 | {154, { 0, L_VAR2} },// "sprmTDefTable" tap.rgtc complex | ||||||
221 | {155, { 1, L_VAR} }, // "sprmTDefTableShd" tap.rgshd complex | ||||||
222 | {157, { 5, L_FIX} }, // "sprmTSetBrc" tap.rgtc[].rgbrc complex 5 bytes | ||||||
223 | {158, { 4, L_FIX} }, // "sprmTInsert" tap.rgdxaCenter,tap.rgtc complex | ||||||
224 | {159, { 2, L_FIX} }, // "sprmTDelete" tap.rgdxaCenter, tap.rgtc complex | ||||||
225 | {160, { 4, L_FIX} }, // "sprmTDxaCol" tap.rgdxaCenter complex | ||||||
226 | {161, { 2, L_FIX} }, // "sprmTMerge" tap.fFirstMerged, tap.fMerged complex | ||||||
227 | {162, { 2, L_FIX} }, // "sprmTSplit" tap.fFirstMerged, tap.fMerged complex | ||||||
228 | {163, { 5, L_FIX} }, // "sprmTSetBrc10" tap.rgtc[].rgbrc complex 5 bytes | ||||||
229 | {164, { 4, L_FIX} }, // "sprmTSetShd", tap.rgshd complex 4 bytes | ||||||
230 | }; | ||||||
231 | |||||||
232 | static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms)(sizeof(sal_n_array_size(aSprms)))); | ||||||
233 | return &aSprmSrch; | ||||||
234 | }; | ||||||
235 | |||||||
236 | const wwSprmSearcher *wwSprmParser::GetWW6SprmSearcher(const WW8Fib& rFib) | ||||||
237 | { | ||||||
238 | //double lock me | ||||||
239 | // WW7- Sprms | ||||||
240 | static const SprmInfoRow aSprms[] = | ||||||
241 | { | ||||||
242 | { 0, { 0, L_FIX} }, // "Default-sprm", is skipped | ||||||
243 | {NS_sprm::v6::sprmPIstd, { 2, L_FIX} }, // pap.istd (style code) | ||||||
244 | {NS_sprm::v6::sprmPIstdPermute, { 3, L_VAR} }, // pap.istd permutation | ||||||
245 | {NS_sprm::v6::sprmPIncLv1, { 1, L_FIX} }, // pap.istddifference | ||||||
246 | {NS_sprm::v6::sprmPJc, { 1, L_FIX} }, // pap.jc (justification) | ||||||
247 | {NS_sprm::v6::sprmPFSideBySide, { 1, L_FIX} }, // pap.fSideBySide | ||||||
248 | {NS_sprm::v6::sprmPFKeep, { 1, L_FIX} }, // pap.fKeep | ||||||
249 | {NS_sprm::v6::sprmPFKeepFollow, { 1, L_FIX} }, // pap.fKeepFollow | ||||||
250 | {NS_sprm::v6::sprmPPageBreakBefore, { 1, L_FIX} }, // pap.fPageBreakBefore | ||||||
251 | {NS_sprm::v6::sprmPBrcl, { 1, L_FIX} }, // pap.brcl | ||||||
252 | {NS_sprm::v6::sprmPBrcp, { 1, L_FIX} }, // pap.brcp | ||||||
253 | {NS_sprm::v6::sprmPAnld, { 0, L_VAR} }, // pap.anld (ANLD structure) | ||||||
254 | {NS_sprm::v6::sprmPNLvlAnm, { 1, L_FIX} }, // pap.nLvlAnm nn | ||||||
255 | {NS_sprm::v6::sprmPFNoLineNumb, { 1, L_FIX} }, // pap.fNoLnn | ||||||
256 | {NS_sprm::v6::sprmPChgTabsPapx, { 0, L_VAR} }, // pap.itbdMac, ... | ||||||
257 | {NS_sprm::v6::sprmPDxaRight, { 2, L_FIX} }, // pap.dxaRight | ||||||
258 | {NS_sprm::v6::sprmPDxaLeft, { 2, L_FIX} }, // pap.dxaLeft | ||||||
259 | {NS_sprm::v6::sprmPNest, { 2, L_FIX} }, // pap.dxaLeft | ||||||
260 | {NS_sprm::v6::sprmPDxaLeft1, { 2, L_FIX} }, // pap.dxaLeft1 | ||||||
261 | {NS_sprm::v6::sprmPDyaLine, { 4, L_FIX} }, // pap.lspd an LSPD | ||||||
262 | {NS_sprm::v6::sprmPDyaBefore, { 2, L_FIX} }, // pap.dyaBefore | ||||||
263 | {NS_sprm::v6::sprmPDyaAfter, { 2, L_FIX} }, // pap.dyaAfter | ||||||
264 | {NS_sprm::v6::sprmPChgTabs, { 0, L_VAR} }, // pap.itbdMac, pap.rgdxaTab, ... | ||||||
265 | {NS_sprm::v6::sprmPFInTable, { 1, L_FIX} }, // pap.fInTable | ||||||
266 | {NS_sprm::v6::sprmPTtp, { 1, L_FIX} }, // pap.fTtp | ||||||
267 | {NS_sprm::v6::sprmPDxaAbs, { 2, L_FIX} }, // pap.dxaAbs | ||||||
268 | {NS_sprm::v6::sprmPDyaAbs, { 2, L_FIX} }, // pap.dyaAbs | ||||||
269 | {NS_sprm::v6::sprmPDxaWidth, { 2, L_FIX} }, // pap.dxaWidth | ||||||
270 | {NS_sprm::v6::sprmPPc, { 1, L_FIX} }, // pap.pcHorz, pap.pcVert | ||||||
271 | {NS_sprm::v6::sprmPBrcTop10, { 2, L_FIX} }, // pap.brcTop BRC10 | ||||||
272 | {NS_sprm::v6::sprmPBrcLeft10, { 2, L_FIX} }, // pap.brcLeft BRC10 | ||||||
273 | {NS_sprm::v6::sprmPBrcBottom10, { 2, L_FIX} }, // pap.brcBottom BRC10 | ||||||
274 | {NS_sprm::v6::sprmPBrcRight10, { 2, L_FIX} }, // pap.brcRight BRC10 | ||||||
275 | {NS_sprm::v6::sprmPBrcBetween10, { 2, L_FIX} }, // pap.brcBetween BRC10 | ||||||
276 | {NS_sprm::v6::sprmPBrcBar10, { 2, L_FIX} }, // pap.brcBar BRC10 | ||||||
277 | {NS_sprm::v6::sprmPFromText10, { 2, L_FIX} }, // pap.dxaFromText dxa | ||||||
278 | {NS_sprm::v6::sprmPWr, { 1, L_FIX} }, // pap.wr wr | ||||||
279 | {NS_sprm::v6::sprmPBrcTop, { 2, L_FIX} }, // pap.brcTop BRC | ||||||
280 | {NS_sprm::v6::sprmPBrcLeft, { 2, L_FIX} }, // pap.brcLeft BRC | ||||||
281 | {NS_sprm::v6::sprmPBrcBottom, { 2, L_FIX} }, // pap.brcBottom BRC | ||||||
282 | {NS_sprm::v6::sprmPBrcRight, { 2, L_FIX} }, // pap.brcRight BRC | ||||||
283 | {NS_sprm::v6::sprmPBrcBetween, { 2, L_FIX} }, // pap.brcBetween BRC | ||||||
284 | {NS_sprm::v6::sprmPBrcBar, { 2, L_FIX} }, // pap.brcBar BRC word | ||||||
285 | {NS_sprm::v6::sprmPFNoAutoHyph, { 1, L_FIX} }, // pap.fNoAutoHyph | ||||||
286 | {NS_sprm::v6::sprmPWHeightAbs, { 2, L_FIX} }, // pap.wHeightAbs w | ||||||
287 | {NS_sprm::v6::sprmPDcs, { 2, L_FIX} }, // pap.dcs DCS | ||||||
288 | {NS_sprm::v6::sprmPShd, { 2, L_FIX} }, // pap.shd SHD | ||||||
289 | {NS_sprm::v6::sprmPDyaFromText, { 2, L_FIX} }, // pap.dyaFromText dya | ||||||
290 | {NS_sprm::v6::sprmPDxaFromText, { 2, L_FIX} }, // pap.dxaFromText dxa | ||||||
291 | {NS_sprm::v6::sprmPFLocked, { 1, L_FIX} }, // pap.fLocked 0 or 1 byte | ||||||
292 | {NS_sprm::v6::sprmPFWidowControl, { 1, L_FIX} }, // pap.fWidowControl 0 or 1 byte | ||||||
293 | {NS_sprm::v6::sprmPRuler, { 0, L_FIX} }, | ||||||
294 | { 64, { 0, L_VAR} }, // rtl property ? | ||||||
295 | {NS_sprm::v6::sprmCFStrikeRM, { 1, L_FIX} }, // chp.fRMarkDel 1 or 0 bit | ||||||
296 | {NS_sprm::v6::sprmCFRMark, { 1, L_FIX} }, // chp.fRMark 1 or 0 bit | ||||||
297 | {NS_sprm::v6::sprmCFFldVanish, { 1, L_FIX} }, // chp.fFieldVanish 1 or 0 bit | ||||||
298 | {NS_sprm::v6::sprmCPicLocation, { 0, L_VAR} }, // chp.fcPic and chp.fSpec | ||||||
299 | {NS_sprm::v6::sprmCIbstRMark, { 2, L_FIX} }, // chp.ibstRMark index into sttbRMark | ||||||
300 | {NS_sprm::v6::sprmCDttmRMark, { 4, L_FIX} }, // chp.dttm DTTM long | ||||||
301 | {NS_sprm::v6::sprmCFData, { 1, L_FIX} }, // chp.fData 1 or 0 bit | ||||||
302 | {NS_sprm::v6::sprmCRMReason, { 2, L_FIX} }, // chp.idslRMReason an index to a table | ||||||
303 | {NS_sprm::v6::sprmCChse, { 3, L_FIX} }, // chp.fChsDiff and chp.chse | ||||||
304 | {NS_sprm::v6::sprmCSymbol, { 0, L_VAR} }, // chp.fSpec, chp.chSym and chp.ftcSym | ||||||
305 | {NS_sprm::v6::sprmCFOle2, { 1, L_FIX} }, // chp.fOle2 1 or 0 bit | ||||||
306 | { 77, { 0, L_VAR} }, // unknown | ||||||
307 | { 79, { 0, L_VAR} }, // unknown | ||||||
308 | {NS_sprm::v6::sprmCIstd, { 2, L_FIX} }, // chp.istd istd, see stylesheet definition | ||||||
309 | {NS_sprm::v6::sprmCIstdPermute, { 0, L_VAR} }, // chp.istd permutation vector | ||||||
310 | {NS_sprm::v6::sprmCDefault, { 0, L_VAR} }, // whole CHP | ||||||
311 | {NS_sprm::v6::sprmCPlain, { 0, L_FIX} }, // whole CHP | ||||||
312 | {NS_sprm::v6::sprmCFBold, { 1, L_FIX} }, // chp.fBold 0,1, 128, or 129 | ||||||
313 | {NS_sprm::v6::sprmCFItalic, { 1, L_FIX} }, // chp.fItalic 0,1, 128, or 129 | ||||||
314 | {NS_sprm::v6::sprmCFStrike, { 1, L_FIX} }, // chp.fStrike 0,1, 128, or 129 | ||||||
315 | {NS_sprm::v6::sprmCFOutline, { 1, L_FIX} }, // chp.fOutline 0,1, 128, or 129 | ||||||
316 | {NS_sprm::v6::sprmCFShadow, { 1, L_FIX} }, // chp.fShadow 0,1, 128, or 129 | ||||||
317 | {NS_sprm::v6::sprmCFSmallCaps, { 1, L_FIX} }, // chp.fSmallCaps 0,1, 128, or 129 | ||||||
318 | {NS_sprm::v6::sprmCFCaps, { 1, L_FIX} }, // chp.fCaps 0,1, 128, or 129 | ||||||
319 | {NS_sprm::v6::sprmCFVanish, { 1, L_FIX} }, // chp.fVanish 0,1, 128, or 129 | ||||||
320 | {NS_sprm::v6::sprmCFtc, { 2, L_FIX} }, // chp.ftc ftc word | ||||||
321 | {NS_sprm::v6::sprmCKul, { 1, L_FIX} }, // chp.kul kul byte | ||||||
322 | {NS_sprm::v6::sprmCSizePos, { 3, L_FIX} }, // chp.hps, chp.hpsPos | ||||||
323 | {NS_sprm::v6::sprmCDxaSpace, { 2, L_FIX} }, // chp.dxaSpace dxa | ||||||
324 | {NS_sprm::v6::sprmCLid, { 2, L_FIX} }, // chp.lid LID | ||||||
325 | {NS_sprm::v6::sprmCIco, { 1, L_FIX} }, // chp.ico ico byte | ||||||
326 | {NS_sprm::v6::sprmCHps, { 2, L_FIX} }, // chp.hps hps !word! | ||||||
327 | {NS_sprm::v6::sprmCHpsInc, { 1, L_FIX} }, // chp.hps | ||||||
328 | {NS_sprm::v6::sprmCHpsPos, { 2, L_FIX} }, // chp.hpsPos hps !word! | ||||||
329 | {NS_sprm::v6::sprmCHpsPosAdj, { 1, L_FIX} }, // chp.hpsPos hps | ||||||
330 | {NS_sprm::v6::sprmCMajority, { 0, L_VAR} }, // chp.fBold, chp.fItalic, ... | ||||||
331 | {NS_sprm::v6::sprmCIss, { 1, L_FIX} }, // chp.iss iss | ||||||
332 | {NS_sprm::v6::sprmCHpsNew50, { 0, L_VAR} }, // chp.hps hps variable width | ||||||
333 | {NS_sprm::v6::sprmCHpsInc1, { 0, L_VAR} }, // chp.hps complex | ||||||
334 | {NS_sprm::v6::sprmCHpsKern, { 2, L_FIX} }, // chp.hpsKern hps | ||||||
335 | {NS_sprm::v6::sprmCMajority50, { 0, L_VAR} }, // chp.fBold, chp.fItalic, ... | ||||||
336 | {NS_sprm::v6::sprmCHpsMul, { 2, L_FIX} }, // chp.hps percentage to grow hps | ||||||
337 | {NS_sprm::v6::sprmCCondHyhen, { 2, L_FIX} }, // chp.ysri ysri | ||||||
338 | {111, { 0, L_VAR} }, // sprmCFBoldBi or font code | ||||||
339 | {112, { 0, L_VAR} }, // sprmCFItalicBi or font code | ||||||
340 | {113, { 0, L_VAR} }, // ww7 rtl font | ||||||
341 | {114, { 0, L_VAR} }, // ww7 lid | ||||||
342 | {115, { 0, L_VAR} }, // ww7 CJK font | ||||||
343 | {116, { 0, L_VAR} }, // ww7 fontsize | ||||||
344 | {NS_sprm::v6::sprmCFSpec, { 1, L_FIX} }, // chp.fSpec 1 or 0 bit | ||||||
345 | {NS_sprm::v6::sprmCFObj, { 1, L_FIX} }, // chp.fObj 1 or 0 bit | ||||||
346 | {NS_sprm::v6::sprmPicBrcl, { 1, L_FIX} }, // pic.brcl brcl (see PIC definition) | ||||||
347 | {NS_sprm::v6::sprmPicScale, {12, L_VAR} }, // pic.mx, pic.my, pic.dxaCropleft, | ||||||
348 | {NS_sprm::v6::sprmPicBrcTop, { 2, L_FIX} }, // pic.brcTop BRC word | ||||||
349 | {NS_sprm::v6::sprmPicBrcLeft, { 2, L_FIX} }, // pic.brcLeft BRC word | ||||||
350 | {NS_sprm::v6::sprmPicBrcBottom, { 2, L_FIX} }, // pic.brcBottom BRC word | ||||||
351 | {NS_sprm::v6::sprmPicBrcRight, { 2, L_FIX} }, // pic.brcRight BRC word | ||||||
352 | {NS_sprm::v6::sprmSScnsPgn, { 1, L_FIX} }, // sep.cnsPgn cns byte | ||||||
353 | {NS_sprm::v6::sprmSiHeadingPgn, { 1, L_FIX} }, // sep.iHeadingPgn | ||||||
354 | {NS_sprm::v6::sprmSOlstAnm, { 0, L_VAR} }, // sep.olstAnm OLST variable length | ||||||
355 | {NS_sprm::v6::sprmSDxaColWidth, { 3, L_FIX} }, // sep.rgdxaColWidthSpacing complex | ||||||
356 | {NS_sprm::v6::sprmSDxaColSpacing, { 3, L_FIX} }, // sep.rgdxaColWidthSpacing | ||||||
357 | {NS_sprm::v6::sprmSFEvenlySpaced, { 1, L_FIX} }, // sep.fEvenlySpaced 1 or 0 | ||||||
358 | {NS_sprm::v6::sprmSFProtected, { 1, L_FIX} }, // sep.fUnlocked 1 or 0 byte | ||||||
359 | {NS_sprm::v6::sprmSDmBinFirst, { 2, L_FIX} }, // sep.dmBinFirst word | ||||||
360 | {NS_sprm::v6::sprmSDmBinOther, { 2, L_FIX} }, // sep.dmBinOther word | ||||||
361 | {NS_sprm::v6::sprmSBkc, { 1, L_FIX} }, // sep.bkc bkc byte | ||||||
362 | {NS_sprm::v6::sprmSFTitlePage, { 1, L_FIX} }, // sep.fTitlePage 0 or 1 byte | ||||||
363 | {NS_sprm::v6::sprmSCcolumns, { 2, L_FIX} }, // sep.ccolM1 # of cols - 1 word | ||||||
364 | {NS_sprm::v6::sprmSDxaColumns, { 2, L_FIX} }, // sep.dxaColumns dxa word | ||||||
365 | {NS_sprm::v6::sprmSFAutoPgn, { 1, L_FIX} }, // sep.fAutoPgn obsolete byte | ||||||
366 | {NS_sprm::v6::sprmSNfcPgn, { 1, L_FIX} }, // sep.nfcPgn nfc byte | ||||||
367 | {NS_sprm::v6::sprmSDyaPgn, { 2, L_FIX} }, // sep.dyaPgn dya short | ||||||
368 | {NS_sprm::v6::sprmSDxaPgn, { 2, L_FIX} }, // sep.dxaPgn dya short | ||||||
369 | {NS_sprm::v6::sprmSFPgnRestart, { 1, L_FIX} }, // sep.fPgnRestart 0 or 1 byte | ||||||
370 | {NS_sprm::v6::sprmSFEndnote, { 1, L_FIX} }, // sep.fEndnote 0 or 1 byte | ||||||
371 | {NS_sprm::v6::sprmSLnc, { 1, L_FIX} }, // sep.lnc lnc byte | ||||||
372 | {NS_sprm::v6::sprmSGprfIhdt, { 1, L_FIX} }, // sep.grpfIhdt grpfihdt | ||||||
373 | {NS_sprm::v6::sprmSNLnnMod, { 2, L_FIX} }, // sep.nLnnMod non-neg int. word | ||||||
374 | {NS_sprm::v6::sprmSDxaLnn, { 2, L_FIX} }, // sep.dxaLnn dxa word | ||||||
375 | {NS_sprm::v6::sprmSDyaHdrTop, { 2, L_FIX} }, // sep.dyaHdrTop dya word | ||||||
376 | {NS_sprm::v6::sprmSDyaHdrBottom, { 2, L_FIX} }, // sep.dyaHdrBottom dya word | ||||||
377 | {NS_sprm::v6::sprmSLBetween, { 1, L_FIX} }, // sep.fLBetween 0 or 1 byte | ||||||
378 | {NS_sprm::v6::sprmSVjc, { 1, L_FIX} }, // sep.vjc vjc byte | ||||||
379 | {NS_sprm::v6::sprmSLnnMin, { 2, L_FIX} }, // sep.lnnMin lnn word | ||||||
380 | {NS_sprm::v6::sprmSPgnStart, { 2, L_FIX} }, // sep.pgnStart pgn word | ||||||
381 | {NS_sprm::v6::sprmSBOrientation, { 1, L_FIX} }, // sep.dmOrientPage dm byte | ||||||
382 | {NS_sprm::v6::sprmSBCustomize, { 0, L_FIX} }, | ||||||
383 | {NS_sprm::v6::sprmSXaPage, { 2, L_FIX} }, // sep.xaPage xa word | ||||||
384 | {NS_sprm::v6::sprmSYaPage, { 2, L_FIX} }, // sep.yaPage ya word | ||||||
385 | {NS_sprm::v6::sprmSDxaLeft, { 2, L_FIX} }, // sep.dxaLeft dxa word | ||||||
386 | {NS_sprm::v6::sprmSDxaRight, { 2, L_FIX} }, // sep.dxaRight dxa word | ||||||
387 | {NS_sprm::v6::sprmSDyaTop, { 2, L_FIX} }, // sep.dyaTop dya word | ||||||
388 | {NS_sprm::v6::sprmSDyaBottom, { 2, L_FIX} }, // sep.dyaBottom dya word | ||||||
389 | {NS_sprm::v6::sprmSDzaGutter, { 2, L_FIX} }, // sep.dzaGutter dza word | ||||||
390 | {NS_sprm::v6::sprmSDMPaperReq, { 2, L_FIX} }, // sep.dmPaperReq dm word | ||||||
391 | {179, { 0, L_VAR} }, // rtl property ? | ||||||
392 | {181, { 0, L_VAR} }, // rtl property ? | ||||||
393 | {NS_sprm::v6::sprmTJc, { 2, L_FIX} }, // tap.jc jc (low order byte is significant) | ||||||
394 | {NS_sprm::v6::sprmTDxaLeft, { 2, L_FIX} }, // tap.rgdxaCenter dxa word | ||||||
395 | {NS_sprm::v6::sprmTDxaGapHalf, { 2, L_FIX} }, // tap.dxaGapHalf, tap.rgdxaCenter | ||||||
396 | {NS_sprm::v6::sprmTFCantSplit, { 1, L_FIX} }, // tap.fCantSplit 1 or 0 byte | ||||||
397 | {NS_sprm::v6::sprmTTableHeader, { 1, L_FIX} }, // tap.fTableHeader 1 or 0 byte | ||||||
398 | {NS_sprm::v6::sprmTTableBorders, {12, L_FIX} }, // tap.rgbrcTable complex 12 bytes | ||||||
399 | {NS_sprm::v6::sprmTDefTable10, { 0, L_VAR} }, // tap.rgdxaCenter, tap.rgtc complex | ||||||
400 | {NS_sprm::v6::sprmTDyaRowHeight, { 2, L_FIX} }, // tap.dyaRowHeight dya word | ||||||
401 | {NS_sprm::v6::sprmTDefTable, { 0, L_VAR2} }, // tap.rgtc complex | ||||||
402 | {NS_sprm::v6::sprmTDefTableShd, { 1, L_VAR} }, // tap.rgshd complex | ||||||
403 | {NS_sprm::v6::sprmTTlp, { 4, L_FIX} }, // tap.tlp TLP 4 bytes | ||||||
404 | {NS_sprm::v6::sprmTSetBrc, { 5, L_FIX} }, // tap.rgtc[].rgbrc complex 5 bytes | ||||||
405 | {NS_sprm::v6::sprmTInsert, { 4, L_FIX} }, // tap.rgdxaCenter,tap.rgtc complex | ||||||
406 | {NS_sprm::v6::sprmTDelete, { 2, L_FIX} }, // tap.rgdxaCenter, tap.rgtc complex | ||||||
407 | {NS_sprm::v6::sprmTDxaCol, { 4, L_FIX} }, // tap.rgdxaCenter complex | ||||||
408 | {NS_sprm::v6::sprmTMerge, { 2, L_FIX} }, // tap.fFirstMerged, tap.fMerged complex | ||||||
409 | {NS_sprm::v6::sprmTSplit, { 2, L_FIX} }, // tap.fFirstMerged, tap.fMerged complex | ||||||
410 | {NS_sprm::v6::sprmTSetBrc10, { 5, L_FIX} }, // tap.rgtc[].rgbrc complex 5 bytes | ||||||
411 | {NS_sprm::v6::sprmTSetShd, { 4, L_FIX} }, // tap.rgshd complex 4 bytes | ||||||
412 | {207, { 0, L_VAR} } // rtl property ? | ||||||
413 | }; | ||||||
414 | |||||||
415 | if (rFib.m_wIdent >= 0xa697 && rFib.m_wIdent <= 0xa699) | ||||||
416 | { | ||||||
417 | //see Read_AmbiguousSPRM for this oddity | ||||||
418 | static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms)(sizeof(sal_n_array_size(aSprms))), true); | ||||||
419 | return &aSprmSrch; | ||||||
420 | } | ||||||
421 | |||||||
422 | static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms)(sizeof(sal_n_array_size(aSprms)))); | ||||||
423 | return &aSprmSrch; | ||||||
424 | }; | ||||||
425 | |||||||
426 | void wwSprmSearcher::patchCJKVariant() | ||||||
427 | { | ||||||
428 | for (sal_uInt16 nId = 111; nId <= 113; ++nId) | ||||||
429 | { | ||||||
430 | SprmInfo& amb1 = map_[nId]; | ||||||
431 | amb1.nLen = 2; | ||||||
432 | amb1.nVari = wwSprmParser::L_FIX; | ||||||
433 | } | ||||||
434 | } | ||||||
435 | |||||||
436 | template <class Sprm> static constexpr SprmInfoRow InfoRow() | ||||||
437 | { | ||||||
438 | return { Sprm::val, { Sprm::len, Sprm::varlen ? wwSprmParser::L_VAR : wwSprmParser::L_FIX } }; | ||||||
439 | } | ||||||
440 | |||||||
441 | const wwSprmSearcher *wwSprmParser::GetWW8SprmSearcher() | ||||||
442 | { | ||||||
443 | //double lock me | ||||||
444 | //WW8+ Sprms | ||||||
445 | static const SprmInfoRow aSprms[] = | ||||||
446 | { | ||||||
447 | { 0, { 0, L_FIX} }, // "Default-sprm"/ is skipped | ||||||
448 | InfoRow<NS_sprm::PIstd>(), // pap.istd;istd (style code);short; | ||||||
449 | InfoRow<NS_sprm::PIstdPermute>(), // pap.istd;permutation vector | ||||||
450 | InfoRow<NS_sprm::PIncLvl>(), // pap.istd, pap.lvl;difference | ||||||
451 | // between istd of base PAP and istd of PAP to be | ||||||
452 | // produced | ||||||
453 | InfoRow<NS_sprm::PJc80>(), // pap.jc;jc (justification);byte; | ||||||
454 | {NS_sprm::LN_PFSideBySide, { 1, L_FIX} }, // "sprmPFSideBySide" pap.fSideBySide;0 or 1;byte; | ||||||
455 | InfoRow<NS_sprm::PFKeep>(), // pap.fKeep;0 or 1;byte; | ||||||
456 | InfoRow<NS_sprm::PFKeepFollow>(), // pap.fKeepFollow;0 or 1;byte; | ||||||
457 | InfoRow<NS_sprm::PFPageBreakBefore>(), // pap.fPageBreakBefore; | ||||||
458 | // 0 or 1 | ||||||
459 | {NS_sprm::LN_PBrcl, { 1, L_FIX} }, // "sprmPBrcl" pap.brcl;brcl;byte; | ||||||
460 | {NS_sprm::LN_PBrcp, { 1, L_FIX} }, // "sprmPBrcp" pap.brcp;brcp;byte; | ||||||
461 | InfoRow<NS_sprm::PIlvl>(), // pap.ilvl;ilvl;byte; | ||||||
462 | InfoRow<NS_sprm::PIlfo>(), // pap.ilfo;ilfo (list index) ;short; | ||||||
463 | InfoRow<NS_sprm::PFNoLineNumb>(), // pap.fNoLnn;0 or 1;byte; | ||||||
464 | InfoRow<NS_sprm::PChgTabsPapx>(), // pap.itbdMac, pap.rgdxaTab, | ||||||
465 | // pap.rgtbd;complex | ||||||
466 | InfoRow<NS_sprm::PDxaRight80>(), // pap.dxaRight;dxa;word; | ||||||
467 | InfoRow<NS_sprm::PDxaLeft80>(), // pap.dxaLeft;dxa;word; | ||||||
468 | InfoRow<NS_sprm::PNest80>(), // pap.dxaLeft;dxa | ||||||
469 | InfoRow<NS_sprm::PDxaLeft180>(), // pap.dxaLeft1;dxa;word; | ||||||
470 | InfoRow<NS_sprm::PDyaLine>(), // pap.lspd;an LSPD, a long word | ||||||
471 | // structure consisting of a short of dyaLine | ||||||
472 | // followed by a short of fMultLinespace | ||||||
473 | InfoRow<NS_sprm::PDyaBefore>(), // pap.dyaBefore;dya;word; | ||||||
474 | InfoRow<NS_sprm::PDyaAfter>(), // pap.dyaAfter;dya;word; | ||||||
475 | InfoRow<NS_sprm::PChgTabs>(), // pap.itbdMac, pap.rgdxaTab, | ||||||
476 | // pap.rgtbd;complex | ||||||
477 | InfoRow<NS_sprm::PFInTable>(), // pap.fInTable;0 or 1;byte; | ||||||
478 | InfoRow<NS_sprm::PFTtp>(), // pap.fTtp;0 or 1;byte; | ||||||
479 | InfoRow<NS_sprm::PDxaAbs>(), // pap.dxaAbs;dxa;word; | ||||||
480 | InfoRow<NS_sprm::PDyaAbs>(), // pap.dyaAbs;dya;word; | ||||||
481 | InfoRow<NS_sprm::PDxaWidth>(), // pap.dxaWidth;dxa;word; | ||||||
482 | InfoRow<NS_sprm::PPc>(), // pap.pcHorz, pap.pcVert;complex | ||||||
483 | {NS_sprm::LN_PBrcTop10, { 2, L_FIX} }, // "sprmPBrcTop10" pap.brcTop;BRC10;word; | ||||||
484 | {NS_sprm::LN_PBrcLeft10, { 2, L_FIX} }, // "sprmPBrcLeft10" pap.brcLeft;BRC10;word; | ||||||
485 | {NS_sprm::LN_PBrcBottom10, { 2, L_FIX} }, // "sprmPBrcBottom10" pap.brcBottom;BRC10;word; | ||||||
486 | {NS_sprm::LN_PBrcRight10, { 2, L_FIX} }, // "sprmPBrcRight10" pap.brcRight;BRC10;word; | ||||||
487 | {NS_sprm::LN_PBrcBetween10, { 2, L_FIX} }, // "sprmPBrcBetween10" pap.brcBetween;BRC10;word; | ||||||
488 | {NS_sprm::LN_PBrcBar10, { 2, L_FIX} }, // "sprmPBrcBar10" pap.brcBar;BRC10;word; | ||||||
489 | {NS_sprm::LN_PDxaFromText10, { 2, L_FIX} }, // "sprmPDxaFromText10" pap.dxaFromText;dxa;word; | ||||||
490 | InfoRow<NS_sprm::PWr>(), // pap.wr;wr | ||||||
491 | InfoRow<NS_sprm::PBrcTop80>(), // pap.brcTop;BRC;long; | ||||||
492 | InfoRow<NS_sprm::PBrcLeft80>(), // pap.brcLeft;BRC;long; | ||||||
493 | InfoRow<NS_sprm::PBrcBottom80>(), // pap.brcBottom;BRC;long; | ||||||
494 | InfoRow<NS_sprm::PBrcRight80>(), // pap.brcRight;BRC;long; | ||||||
495 | InfoRow<NS_sprm::PBrcBetween80>(), // pap.brcBetween;BRC;long; | ||||||
496 | InfoRow<NS_sprm::PBrcBar80>(), // pap.brcBar;BRC;long; | ||||||
497 | InfoRow<NS_sprm::PFNoAutoHyph>(), // pap.fNoAutoHyph;0 or 1;byte; | ||||||
498 | InfoRow<NS_sprm::PWHeightAbs>(), // pap.wHeightAbs;w;word; | ||||||
499 | InfoRow<NS_sprm::PDcs>(), // pap.dcs;DCS;short; | ||||||
500 | InfoRow<NS_sprm::PShd80>(), // pap.shd;SHD;word; | ||||||
501 | InfoRow<NS_sprm::PDyaFromText>(), // pap.dyaFromText;dya;word; | ||||||
502 | InfoRow<NS_sprm::PDxaFromText>(), // pap.dxaFromText;dxa;word; | ||||||
503 | InfoRow<NS_sprm::PFLocked>(), // pap.fLocked;0 or 1;byte; | ||||||
504 | InfoRow<NS_sprm::PFWidowControl>(), // pap.fWidowControl;0 or 1 | ||||||
505 | {NS_sprm::LN_PRuler, { 0, L_VAR} }, // "sprmPRuler" ;;variable length; | ||||||
506 | InfoRow<NS_sprm::PFKinsoku>(), // pap.fKinsoku;0 or 1;byte; | ||||||
507 | InfoRow<NS_sprm::PFWordWrap>(), // pap.fWordWrap;0 or 1;byte; | ||||||
508 | InfoRow<NS_sprm::PFOverflowPunct>(), // pap.fOverflowPunct;0 or 1 | ||||||
509 | InfoRow<NS_sprm::PFTopLinePunct>(), // pap.fTopLinePunct;0 or 1 | ||||||
510 | InfoRow<NS_sprm::PFAutoSpaceDE>(), // pap.fAutoSpaceDE;0 or 1 | ||||||
511 | InfoRow<NS_sprm::PFAutoSpaceDN>(), // pap.fAutoSpaceDN;0 or 1 | ||||||
512 | InfoRow<NS_sprm::PWAlignFont>(), // pap.wAlignFont;iFa | ||||||
513 | InfoRow<NS_sprm::PFrameTextFlow>(), // pap.fVertical pap.fBackward | ||||||
514 | // pap.fRotateFont;complex | ||||||
515 | {NS_sprm::LN_PISnapBaseLine, { 1, L_FIX} }, // "sprmPISnapBaseLine" obsolete: not applicable in | ||||||
516 | // Word97 and later versions; | ||||||
517 | {NS_sprm::LN_PAnld, { 0, L_VAR} }, // "sprmPAnld" pap.anld;;variable length; | ||||||
518 | {NS_sprm::LN_PPropRMark, { 0, L_VAR} }, // "sprmPPropRMark" pap.fPropRMark;complex | ||||||
519 | InfoRow<NS_sprm::POutLvl>(), // pap.lvl;has no effect if pap.istd | ||||||
520 | // is < 1 or is > 9 | ||||||
521 | InfoRow<NS_sprm::PFBiDi>(), // ;;byte; | ||||||
522 | InfoRow<NS_sprm::PFNumRMIns>(), // pap.fNumRMIns;1 or 0;bit; | ||||||
523 | {NS_sprm::LN_PCrLf, { 1, L_FIX} }, // "sprmPCrLf" ;;byte; | ||||||
524 | InfoRow<NS_sprm::PNumRM>(), // pap.numrm;;variable length; | ||||||
525 | {NS_sprm::LN_PHugePapx, { 4, L_FIX} }, // "sprmPHugePapx" fc in the data stream to locate | ||||||
526 | // the huge grpprl | ||||||
527 | InfoRow<NS_sprm::PHugePapx>(), // fc in the data stream to locate | ||||||
528 | // the huge grpprl | ||||||
529 | InfoRow<NS_sprm::PFUsePgsuSettings>(), // pap.fUsePgsuSettings; | ||||||
530 | // 1 or 0 | ||||||
531 | InfoRow<NS_sprm::PFAdjustRight>(), // pap.fAdjustRight;1 or 0;byte; | ||||||
532 | InfoRow<NS_sprm::CFRMarkDel>(), // chp.fRMarkDel;1 or 0;bit; | ||||||
533 | InfoRow<NS_sprm::CFRMarkIns>(), // chp.fRMark;1 or 0;bit; | ||||||
534 | InfoRow<NS_sprm::CFFldVanish>(), // chp.fFieldVanish;1 or 0;bit; | ||||||
535 | InfoRow<NS_sprm::CPicLocation>(), // chp.fcPic and chp.fSpec; | ||||||
536 | InfoRow<NS_sprm::CIbstRMark>(), // chp.ibstRMark;index into | ||||||
537 | // sttbRMark | ||||||
538 | InfoRow<NS_sprm::CDttmRMark>(), // chp.dttmRMark;DTTM;long; | ||||||
539 | InfoRow<NS_sprm::CFData>(), // chp.fData;1 or 0;bit; | ||||||
540 | InfoRow<NS_sprm::CIdslRMark>(), // chp.idslRMReason;an index to a | ||||||
541 | // table of strings defined in Word 6.0 | ||||||
542 | // executables;short; | ||||||
543 | {NS_sprm::LN_CChs, { 1, L_FIX} }, // "sprmCChs" chp.fChsDiff and chp.chse; | ||||||
544 | InfoRow<NS_sprm::CSymbol>(), // chp.fSpec, chp.xchSym and | ||||||
545 | // chp.ftcSym | ||||||
546 | InfoRow<NS_sprm::CFOle2>(), // chp.fOle2;1 or 0;bit; | ||||||
547 | {NS_sprm::LN_CIdCharType, { 0, L_FIX} }, // "sprmCIdCharType" obsolete: not applicable in | ||||||
548 | // Word97 and later versions; | ||||||
549 | InfoRow<NS_sprm::CHighlight>(), // chp.fHighlight, | ||||||
550 | // chp.icoHighlight;ico (fHighlight is set to 1 iff | ||||||
551 | // ico is not 0) | ||||||
552 | {NS_sprm::LN_CObjLocation, { 4, L_FIX} }, // "sprmCObjLocation" chp.fcObj;FC;long; | ||||||
553 | {NS_sprm::LN_CFFtcAsciSymb, { 0, L_FIX} }, // "sprmCFFtcAsciSymb" ;;; | ||||||
554 | InfoRow<NS_sprm::CIstd>(), // chp.istd;istd, see stylesheet def | ||||||
555 | InfoRow<NS_sprm::CIstdPermute>(), // chp.istd;permutation vector | ||||||
556 | {NS_sprm::LN_CDefault, { 0, L_VAR} }, // "sprmCDefault" whole CHP;none;variable length; | ||||||
557 | InfoRow<NS_sprm::CPlain>(), // whole CHP;none;0; | ||||||
558 | InfoRow<NS_sprm::CKcd>(), // ;;; | ||||||
559 | InfoRow<NS_sprm::CFBold>(), // chp.fBold;0,1, 128, or 129 | ||||||
560 | InfoRow<NS_sprm::CFItalic>(), // chp.fItalic;0,1, 128, or 129 | ||||||
561 | InfoRow<NS_sprm::CFStrike>(), // chp.fStrike;0,1, 128, or 129 | ||||||
562 | InfoRow<NS_sprm::CFOutline>(), // chp.fOutline;0,1, 128, or 129 | ||||||
563 | InfoRow<NS_sprm::CFShadow>(), // chp.fShadow;0,1, 128, or 129 | ||||||
564 | InfoRow<NS_sprm::CFSmallCaps>(), // chp.fSmallCaps;0,1, 128, or 129 | ||||||
565 | InfoRow<NS_sprm::CFCaps>(), // chp.fCaps;0,1, 128, or 129 | ||||||
566 | InfoRow<NS_sprm::CFVanish>(), // chp.fVanish;0,1, 128, or 129 | ||||||
567 | {NS_sprm::LN_CFtcDefault, { 2, L_FIX} }, // "sprmCFtcDefault" ;ftc, only used internally | ||||||
568 | InfoRow<NS_sprm::CKul>(), // chp.kul;kul;byte; | ||||||
569 | {NS_sprm::LN_CSizePos, { 3, L_FIX} }, // "sprmCSizePos" chp.hps, chp.hpsPos;3 bytes; | ||||||
570 | InfoRow<NS_sprm::CDxaSpace>(), // chp.dxaSpace;dxa;word; | ||||||
571 | {NS_sprm::LN_CLid, { 2, L_FIX} }, // "sprmCLid" ;only used internally never stored | ||||||
572 | InfoRow<NS_sprm::CIco>(), // chp.ico;ico;byte; | ||||||
573 | InfoRow<NS_sprm::CHps>(), // chp.hps;hps | ||||||
574 | {NS_sprm::LN_CHpsInc, { 1, L_FIX} }, // "sprmCHpsInc" chp.hps; | ||||||
575 | InfoRow<NS_sprm::CHpsPos>(), // chp.hpsPos;hps;short; (doc wrong) | ||||||
576 | {NS_sprm::LN_CHpsPosAdj, { 1, L_FIX} }, // "sprmCHpsPosAdj" chp.hpsPos;hps | ||||||
577 | InfoRow<NS_sprm::CMajority>(), // chp.fBold, chp.fItalic, | ||||||
578 | // chp.fSmallCaps, chp.fVanish, chp.fStrike, | ||||||
579 | // chp.fCaps, chp.rgftc, chp.hps, chp.hpsPos, | ||||||
580 | // chp.kul, chp.dxaSpace, chp.ico, | ||||||
581 | // chp.rglid;complex;variable length, length byte | ||||||
582 | // plus size of following grpprl; | ||||||
583 | InfoRow<NS_sprm::CIss>(), // chp.iss;iss;byte; | ||||||
584 | {NS_sprm::LN_CHpsNew50, { 0, L_VAR} }, // "sprmCHpsNew50" chp.hps;hps;variable width | ||||||
585 | {NS_sprm::LN_CHpsInc1, { 0, L_VAR} }, // "sprmCHpsInc1" chp.hps;complex | ||||||
586 | InfoRow<NS_sprm::CHpsKern>(), // chp.hpsKern;hps;short; | ||||||
587 | {NS_sprm::LN_CMajority50, { 2, L_FIX} }, // "sprmCMajority50" chp.fBold, chp.fItalic, | ||||||
588 | // chp.fSmallCaps, chp.fVanish, chp.fStrike, | ||||||
589 | // chp.fCaps, chp.ftc, chp.hps, chp.hpsPos, chp.kul, | ||||||
590 | // chp.dxaSpace, chp.ico,;complex | ||||||
591 | {NS_sprm::LN_CHpsMul, { 2, L_FIX} }, // "sprmCHpsMul" chp.hps;percentage to grow hps | ||||||
592 | InfoRow<NS_sprm::CHresi>(), // chp.ysri;ysri;short; | ||||||
593 | InfoRow<NS_sprm::CRgFtc0>(), // chp.rgftc[0];ftc for ASCII text | ||||||
594 | InfoRow<NS_sprm::CRgFtc1>(), // chp.rgftc[1];ftc for Far East text | ||||||
595 | InfoRow<NS_sprm::CRgFtc2>(), // chp.rgftc[2];ftc for non-FE text | ||||||
596 | InfoRow<NS_sprm::CCharScale>(), | ||||||
597 | InfoRow<NS_sprm::CFDStrike>(), // chp.fDStrike;;byte; | ||||||
598 | InfoRow<NS_sprm::CFImprint>(), // chp.fImprint;1 or 0;bit; | ||||||
599 | InfoRow<NS_sprm::CFSpec>(), // chp.fSpec ;1 or 0;bit; | ||||||
600 | InfoRow<NS_sprm::CFObj>(), // chp.fObj;1 or 0;bit; | ||||||
601 | InfoRow<NS_sprm::CPropRMark90>(), // chp.fPropRMark, | ||||||
602 | // chp.ibstPropRMark, chp.dttmPropRMark;Complex | ||||||
603 | InfoRow<NS_sprm::CFEmboss>(), // chp.fEmboss;1 or 0;bit; | ||||||
604 | InfoRow<NS_sprm::CSfxText>(), // chp.sfxtText;text animation;byte; | ||||||
605 | InfoRow<NS_sprm::CFBiDi>(), // ;;; | ||||||
606 | {NS_sprm::LN_CFDiacColor, { 1, L_FIX} }, // "sprmCFDiacColor" ;;; | ||||||
607 | InfoRow<NS_sprm::CFBoldBi>(), // ;;; | ||||||
608 | InfoRow<NS_sprm::CFItalicBi>(), // ;;; | ||||||
609 | InfoRow<NS_sprm::CFtcBi>(), | ||||||
610 | InfoRow<NS_sprm::CLidBi>(), // ;;; | ||||||
611 | InfoRow<NS_sprm::CIcoBi>(), // ;;; | ||||||
612 | InfoRow<NS_sprm::CHpsBi>(), // ;;; | ||||||
613 | InfoRow<NS_sprm::CDispFldRMark>(), // chp.fDispFieldRMark, | ||||||
614 | // chp.ibstDispFieldRMark, chp.dttmDispFieldRMark ; | ||||||
615 | InfoRow<NS_sprm::CIbstRMarkDel>(), // chp.ibstRMarkDel;index into | ||||||
616 | // sttbRMark;short; | ||||||
617 | InfoRow<NS_sprm::CDttmRMarkDel>(), // chp.dttmRMarkDel;DTTM;long; | ||||||
618 | InfoRow<NS_sprm::CBrc80>(), // chp.brc;BRC;long; | ||||||
619 | InfoRow<NS_sprm::CShd80>(), // chp.shd;SHD;short; | ||||||
620 | InfoRow<NS_sprm::CIdslRMarkDel>(), // chp.idslRMReasonDel;an index | ||||||
621 | // to a table of strings defined in Word 6.0 | ||||||
622 | // executables;short; | ||||||
623 | InfoRow<NS_sprm::CFUsePgsuSettings>(), | ||||||
624 | // chp.fUsePgsuSettings;1 or 0 | ||||||
625 | {NS_sprm::LN_CCpg, { 2, L_FIX} }, // "sprmCCpg" ;;word; | ||||||
626 | InfoRow<NS_sprm::CRgLid0_80>(), // chp.rglid[0];LID: for non-FE text | ||||||
627 | InfoRow<NS_sprm::CRgLid1_80>(), // chp.rglid[1];LID: for Far East text | ||||||
628 | InfoRow<NS_sprm::CIdctHint>(), // chp.idctHint;IDCT: | ||||||
629 | {NS_sprm::LN_PicBrcl, { 1, L_FIX} }, // "sprmPicBrcl" pic.brcl;brcl (see PIC definition) | ||||||
630 | {NS_sprm::LN_PicScale, { 0, L_VAR} }, // "sprmPicScale" pic.mx, pic.my, pic.dxaCropleft, | ||||||
631 | // pic.dyaCropTop pic.dxaCropRight, | ||||||
632 | // pic.dyaCropBottom;Complex | ||||||
633 | InfoRow<NS_sprm::PicBrcTop80>(), // pic.brcTop;BRC;long; | ||||||
634 | InfoRow<NS_sprm::PicBrcLeft80>(), // pic.brcLeft;BRC;long; | ||||||
635 | InfoRow<NS_sprm::PicBrcBottom80>(), // pic.brcBottom;BRC;long; | ||||||
636 | InfoRow<NS_sprm::PicBrcRight80>(), // pic.brcRight;BRC;long; | ||||||
637 | InfoRow<NS_sprm::ScnsPgn>(), // sep.cnsPgn;cns;byte; | ||||||
638 | InfoRow<NS_sprm::SiHeadingPgn>(), // sep.iHeadingPgn;heading number | ||||||
639 | // level;byte; | ||||||
640 | {NS_sprm::LN_SOlstAnm, { 0, L_VAR} }, // "sprmSOlstAnm" sep.olstAnm;OLST;variable length; | ||||||
641 | InfoRow<NS_sprm::SDxaColWidth>(), // sep.rgdxaColWidthSpacing; | ||||||
642 | InfoRow<NS_sprm::SDxaColSpacing>(), // sep.rgdxaColWidthSpacing; | ||||||
643 | // complex | ||||||
644 | InfoRow<NS_sprm::SFEvenlySpaced>(), // sep.fEvenlySpaced;1 or 0 | ||||||
645 | InfoRow<NS_sprm::SFProtected>(), // sep.fUnlocked;1 or 0;byte; | ||||||
646 | InfoRow<NS_sprm::SDmBinFirst>(), // sep.dmBinFirst;;word; | ||||||
647 | InfoRow<NS_sprm::SDmBinOther>(), // sep.dmBinOther;;word; | ||||||
648 | InfoRow<NS_sprm::SBkc>(), // sep.bkc;bkc;byte; | ||||||
649 | InfoRow<NS_sprm::SFTitlePage>(), // sep.fTitlePage;0 or 1;byte; | ||||||
650 | InfoRow<NS_sprm::SCcolumns>(), // sep.ccolM1;# of cols - 1;word; | ||||||
651 | InfoRow<NS_sprm::SDxaColumns>(), // sep.dxaColumns;dxa;word; | ||||||
652 | {NS_sprm::LN_SFAutoPgn, { 1, L_FIX} }, // "sprmSFAutoPgn" sep.fAutoPgn;obsolete;byte; | ||||||
653 | InfoRow<NS_sprm::SNfcPgn>(), // sep.nfcPgn;nfc;byte; | ||||||
654 | {NS_sprm::LN_SDyaPgn, { 2, L_FIX} }, // "sprmSDyaPgn" sep.dyaPgn;dya;short; | ||||||
655 | {NS_sprm::LN_SDxaPgn, { 2, L_FIX} }, // "sprmSDxaPgn" sep.dxaPgn;dya;short; | ||||||
656 | InfoRow<NS_sprm::SFPgnRestart>(), // sep.fPgnRestart;0 or 1;byte; | ||||||
657 | InfoRow<NS_sprm::SFEndnote>(), // sep.fEndnote;0 or 1;byte; | ||||||
658 | InfoRow<NS_sprm::SLnc>(), // sep.lnc;lnc;byte; | ||||||
659 | {NS_sprm::LN_SGprfIhdt, { 1, L_FIX} }, // "sprmSGprfIhdt" sep.grpfIhdt;grpfihdt | ||||||
660 | InfoRow<NS_sprm::SNLnnMod>(), // sep.nLnnMod;non-neg int.;word; | ||||||
661 | InfoRow<NS_sprm::SDxaLnn>(), // sep.dxaLnn;dxa;word; | ||||||
662 | InfoRow<NS_sprm::SDyaHdrTop>(), // sep.dyaHdrTop;dya;word; | ||||||
663 | InfoRow<NS_sprm::SDyaHdrBottom>(), // sep.dyaHdrBottom;dya;word; | ||||||
664 | InfoRow<NS_sprm::SLBetween>(), // sep.fLBetween;0 or 1;byte; | ||||||
665 | InfoRow<NS_sprm::SVjc>(), // sep.vjc;vjc;byte; | ||||||
666 | InfoRow<NS_sprm::SLnnMin>(), // sep.lnnMin;lnn;word; | ||||||
667 | InfoRow<NS_sprm::SPgnStart97>(), // sep.pgnStart;pgn;word; | ||||||
668 | InfoRow<NS_sprm::SBOrientation>(), // sep.dmOrientPage;dm;byte; | ||||||
669 | {NS_sprm::LN_SBCustomize, { 1, L_FIX} }, // "sprmSBCustomize" ;;; | ||||||
670 | InfoRow<NS_sprm::SXaPage>(), // sep.xaPage;xa;word; | ||||||
671 | InfoRow<NS_sprm::SYaPage>(), // sep.yaPage;ya;word; | ||||||
672 | InfoRow<NS_sprm::SDxaLeft>(), // sep.dxaLeft;dxa;word; | ||||||
673 | InfoRow<NS_sprm::SDxaRight>(), // sep.dxaRight;dxa;word; | ||||||
674 | InfoRow<NS_sprm::SDyaTop>(), // sep.dyaTop;dya;word; | ||||||
675 | InfoRow<NS_sprm::SDyaBottom>(), // sep.dyaBottom;dya;word; | ||||||
676 | InfoRow<NS_sprm::SDzaGutter>(), // sep.dzaGutter;dza;word; | ||||||
677 | InfoRow<NS_sprm::SDmPaperReq>(), // sep.dmPaperReq;dm;word; | ||||||
678 | {NS_sprm::LN_SPropRMark, { 0, L_VAR} }, // "sprmSPropRMark" sep.fPropRMark, | ||||||
679 | // sep.ibstPropRMark, sep.dttmPropRMark ;complex | ||||||
680 | InfoRow<NS_sprm::SFBiDi>(), // ;;; | ||||||
681 | {NS_sprm::LN_SFFacingCol, { 1, L_FIX} }, // "sprmSFFacingCol" ;;; | ||||||
682 | InfoRow<NS_sprm::SFRTLGutter>(), //, set to one if gutter is on | ||||||
683 | // right | ||||||
684 | InfoRow<NS_sprm::SBrcTop80>(), // sep.brcTop;BRC;long; | ||||||
685 | InfoRow<NS_sprm::SBrcLeft80>(), // sep.brcLeft;BRC;long; | ||||||
686 | InfoRow<NS_sprm::SBrcBottom80>(), // sep.brcBottom;BRC;long; | ||||||
687 | InfoRow<NS_sprm::SBrcRight80>(), // sep.brcRight;BRC;long; | ||||||
688 | InfoRow<NS_sprm::SPgbProp>(), // sep.pgbProp;;word; | ||||||
689 | InfoRow<NS_sprm::SDxtCharSpace>(), // sep.dxtCharSpace;dxt;long; | ||||||
690 | InfoRow<NS_sprm::SDyaLinePitch>(), | ||||||
691 | // sep.dyaLinePitch;dya; WRONG:long; RIGHT:short; ! | ||||||
692 | InfoRow<NS_sprm::SClm>(), // ;;; | ||||||
693 | InfoRow<NS_sprm::STextFlow>(), // sep.wTextFlow;complex | ||||||
694 | InfoRow<NS_sprm::TJc90>(), // tap.jc;jc;word (low order byte is | ||||||
695 | // significant); | ||||||
696 | InfoRow<NS_sprm::TDxaLeft>(), // tap.rgdxaCenter | ||||||
697 | InfoRow<NS_sprm::TDxaGapHalf>(), // tap.dxaGapHalf, | ||||||
698 | // tap.rgdxaCenter | ||||||
699 | InfoRow<NS_sprm::TFCantSplit90>(), // tap.fCantSplit90;1 or 0;byte; | ||||||
700 | InfoRow<NS_sprm::TTableHeader>(), // tap.fTableHeader;1 or 0;byte; | ||||||
701 | InfoRow<NS_sprm::TFCantSplit>(), // tap.fCantSplit;1 or 0;byte; | ||||||
702 | InfoRow<NS_sprm::TTableBorders80>(), // tap.rgbrcTable;complex | ||||||
703 | {NS_sprm::LN_TDefTable10, { 0, L_VAR} }, // "sprmTDefTable10" tap.rgdxaCenter, | ||||||
704 | // tap.rgtc;complex | ||||||
705 | InfoRow<NS_sprm::TDyaRowHeight>(), // tap.dyaRowHeight;dya;word; | ||||||
706 | InfoRow<NS_sprm::TDefTable>(), // tap.rgtc;complex | ||||||
707 | InfoRow<NS_sprm::TDefTableShd80>(), // tap.rgshd;complex | ||||||
708 | InfoRow<NS_sprm::TTlp>(), // tap.tlp;TLP;4 bytes; | ||||||
709 | InfoRow<NS_sprm::TFBiDi>(), // ;;; | ||||||
710 | {NS_sprm::LN_THTMLProps, { 1, L_FIX} }, // "sprmTHTMLProps" ;;; | ||||||
711 | InfoRow<NS_sprm::TSetBrc80>(), // tap.rgtc[].rgbrc;complex | ||||||
712 | InfoRow<NS_sprm::TInsert>(), // tap.rgdxaCenter, tap.rgtc;complex | ||||||
713 | InfoRow<NS_sprm::TDelete>(), // tap.rgdxaCenter, tap.rgtc;complex | ||||||
714 | InfoRow<NS_sprm::TDxaCol>(), // tap.rgdxaCenter;complex | ||||||
715 | InfoRow<NS_sprm::TMerge>(), // tap.fFirstMerged, tap.fMerged; | ||||||
716 | InfoRow<NS_sprm::TSplit>(), // tap.fFirstMerged, tap.fMerged; | ||||||
717 | {NS_sprm::LN_TSetBrc10, { 0, L_VAR} }, // "sprmTSetBrc10" tap.rgtc[].rgbrc;complex | ||||||
718 | {NS_sprm::LN_TSetShd80, { 0, L_VAR} }, // "sprmTSetShd80" tap.rgshd;complex | ||||||
719 | {NS_sprm::LN_TSetShdOdd80, { 0, L_VAR} }, // "sprmTSetShdOdd80" tap.rgshd;complex | ||||||
720 | InfoRow<NS_sprm::TTextFlow>(), // tap.rgtc[].fVerticaltap, | ||||||
721 | // rgtc[].fBackwardtap, rgtc[].fRotateFont;0 or 10 | ||||||
722 | // or 10 or 1;word; | ||||||
723 | {NS_sprm::LN_TDiagLine, { 1, L_FIX} }, // "sprmTDiagLine" ;;; | ||||||
724 | InfoRow<NS_sprm::TVertMerge>(), // tap.rgtc[].vertMerge | ||||||
725 | InfoRow<NS_sprm::TVertAlign>(), // tap.rgtc[].vertAlign | ||||||
726 | InfoRow<NS_sprm::CFELayout>(), | ||||||
727 | InfoRow<NS_sprm::PItap>(), // undocumented | ||||||
728 | InfoRow<NS_sprm::TTableWidth>(), // undocumented | ||||||
729 | InfoRow<NS_sprm::TDefTableShd>(), | ||||||
730 | InfoRow<NS_sprm::TTableBorders>(), | ||||||
731 | InfoRow<NS_sprm::TBrcTopCv>(), // undocumented | ||||||
732 | InfoRow<NS_sprm::TBrcLeftCv>(), // undocumented | ||||||
733 | InfoRow<NS_sprm::TBrcBottomCv>(), // undocumented | ||||||
734 | InfoRow<NS_sprm::TBrcRightCv>(), // undocumented | ||||||
735 | InfoRow<NS_sprm::TCellPadding>(), // undocumented | ||||||
736 | InfoRow<NS_sprm::TCellPaddingDefault>(), // undocumented | ||||||
737 | {0xD238, { 0, L_VAR} }, // undocumented sep | ||||||
738 | InfoRow<NS_sprm::PBrcTop>(), | ||||||
739 | InfoRow<NS_sprm::PBrcLeft>(), | ||||||
740 | InfoRow<NS_sprm::PBrcBottom>(), | ||||||
741 | InfoRow<NS_sprm::PBrcRight>(), | ||||||
742 | InfoRow<NS_sprm::PBrcBetween>(), | ||||||
743 | InfoRow<NS_sprm::TWidthIndent>(), // undocumented | ||||||
744 | InfoRow<NS_sprm::CRgLid0>(), // chp.rglid[0];LID: for non-FE text | ||||||
745 | InfoRow<NS_sprm::CRgLid1>(), // chp.rglid[1];LID: for Far East text | ||||||
746 | {0x6463, { 4, L_FIX} }, // undocumented | ||||||
747 | InfoRow<NS_sprm::PJc>(), // undoc, must be asian version of "sprmPJc" | ||||||
748 | InfoRow<NS_sprm::PDxaRight>(), // undoc, must be asian version of "sprmPDxaRight" | ||||||
749 | InfoRow<NS_sprm::PDxaLeft>(), // undoc, must be asian version of "sprmPDxaLeft" | ||||||
750 | InfoRow<NS_sprm::PDxaLeft1>(), // undoc, must be asian version of "sprmPDxaLeft1" | ||||||
751 | InfoRow<NS_sprm::TFAutofit>(), // undocumented | ||||||
752 | InfoRow<NS_sprm::TPc>(), // undocumented | ||||||
753 | InfoRow<NS_sprm::SRsid>(), // undocumented, sep, perhaps related to textgrids ? | ||||||
754 | InfoRow<NS_sprm::SFpc>(), // undocumented, sep | ||||||
755 | InfoRow<NS_sprm::PFInnerTableCell>(), // undocumented, subtable "sprmPFInTable" equiv ? | ||||||
756 | InfoRow<NS_sprm::PFInnerTtp>(), // undocumented, subtable "sprmPFTtp" equiv ? | ||||||
757 | InfoRow<NS_sprm::TDxaAbs>(), // undocumented | ||||||
758 | InfoRow<NS_sprm::TDyaAbs>(), // undocumented | ||||||
759 | InfoRow<NS_sprm::TDxaFromText>(), // undocumented | ||||||
760 | InfoRow<NS_sprm::CRsidProp>(), // undocumented | ||||||
761 | InfoRow<NS_sprm::CRsidText>(), // undocumented | ||||||
762 | InfoRow<NS_sprm::CCv>(), // text colour | ||||||
763 | InfoRow<NS_sprm::PShd>(), // undocumented, para back colour | ||||||
764 | InfoRow<NS_sprm::PRsid>(), // undocumented | ||||||
765 | InfoRow<NS_sprm::PTableProps>(), // undocumented | ||||||
766 | InfoRow<NS_sprm::TWidthBefore>(), // undocumented | ||||||
767 | InfoRow<NS_sprm::TSetShdTable>(), // undocumented, something to do with colour. | ||||||
768 | InfoRow<NS_sprm::TDefTableShdRaw>(), // undocumented, something to do with colour. | ||||||
769 | InfoRow<NS_sprm::CShd>(), // text backcolour | ||||||
770 | InfoRow<NS_sprm::SRncFtn>(), // undocumented, sep | ||||||
771 | InfoRow<NS_sprm::PFDyaBeforeAuto>(), // undocumented, para autobefore | ||||||
772 | InfoRow<NS_sprm::PFDyaAfterAuto>(), // undocumented, para autoafter | ||||||
773 | // "sprmPFContextualSpacing", don't add space between para of the same style | ||||||
774 | InfoRow<NS_sprm::PFContextualSpacing>(), | ||||||
775 | }; | ||||||
776 | |||||||
777 | static wwSprmSearcher aSprmSrch(aSprms, SAL_N_ELEMENTS(aSprms)(sizeof(sal_n_array_size(aSprms)))); | ||||||
778 | return &aSprmSrch; | ||||||
779 | }; | ||||||
780 | |||||||
781 | wwSprmParser::wwSprmParser(const WW8Fib& rFib) : meVersion(rFib.GetFIBVersion()) | ||||||
782 | { | ||||||
783 | OSL_ENSURE((meVersion >= ww::eWW1 && meVersion <= ww::eWW8),do { if (true && (!((meVersion >= ww::eWW1 && meVersion <= ww::eWW8)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "784" ": "), "%s", "Impossible value for version"); } } while (false) | ||||||
784 | "Impossible value for version")do { if (true && (!((meVersion >= ww::eWW1 && meVersion <= ww::eWW8)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "784" ": "), "%s", "Impossible value for version"); } } while (false); | ||||||
785 | |||||||
786 | mnDelta = (ww::IsSevenMinus(meVersion)) ? 0 : 1; | ||||||
787 | |||||||
788 | if (meVersion <= ww::eWW2) | ||||||
789 | mpKnownSprms = GetWW2SprmSearcher(); | ||||||
790 | else if (meVersion < ww::eWW8) | ||||||
791 | mpKnownSprms = GetWW6SprmSearcher(rFib); | ||||||
792 | else | ||||||
793 | mpKnownSprms = GetWW8SprmSearcher(); | ||||||
794 | } | ||||||
795 | |||||||
796 | SprmInfo wwSprmParser::GetSprmInfo(sal_uInt16 nId) const | ||||||
797 | { | ||||||
798 | const SprmInfo* pFound = mpKnownSprms->search(nId); | ||||||
799 | if (pFound != nullptr) | ||||||
800 | { | ||||||
801 | return *pFound; | ||||||
802 | } | ||||||
803 | |||||||
804 | OSL_ENSURE(ww::IsEightPlus(meVersion),do { if (true && (!(ww::IsEightPlus(meVersion)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "805" ": "), "%s", "Unknown ww7- sprm, dangerous, report to development" ); } } while (false) | ||||||
805 | "Unknown ww7- sprm, dangerous, report to development")do { if (true && (!(ww::IsEightPlus(meVersion)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "805" ": "), "%s", "Unknown ww7- sprm, dangerous, report to development" ); } } while (false); | ||||||
806 | |||||||
807 | //All the unknown ww7 sprms appear to be variable (which makes sense) | ||||||
808 | SprmInfo aSrch = { 0, L_VAR }; | ||||||
809 | if (ww::IsEightPlus(meVersion)) //We can recover perfectly in this case | ||||||
810 | { | ||||||
811 | aSrch.nVari = L_FIX; | ||||||
812 | switch (nId >> 13) | ||||||
813 | { | ||||||
814 | case 0: | ||||||
815 | case 1: | ||||||
816 | aSrch.nLen = 1; | ||||||
817 | break; | ||||||
818 | case 2: | ||||||
819 | aSrch.nLen = 2; | ||||||
820 | break; | ||||||
821 | case 3: | ||||||
822 | aSrch.nLen = 4; | ||||||
823 | break; | ||||||
824 | case 4: | ||||||
825 | case 5: | ||||||
826 | aSrch.nLen = 2; | ||||||
827 | break; | ||||||
828 | case 6: | ||||||
829 | aSrch.nLen = 0; | ||||||
830 | aSrch.nVari = L_VAR; | ||||||
831 | break; | ||||||
832 | case 7: | ||||||
833 | default: | ||||||
834 | aSrch.nLen = 3; | ||||||
835 | break; | ||||||
836 | } | ||||||
837 | } | ||||||
838 | return aSrch; | ||||||
839 | } | ||||||
840 | |||||||
841 | //-end | ||||||
842 | |||||||
843 | static sal_uInt8 Get_Byte( sal_uInt8 *& p ) | ||||||
844 | { | ||||||
845 | sal_uInt8 n = *p; | ||||||
846 | p += 1; | ||||||
847 | return n; | ||||||
848 | } | ||||||
849 | |||||||
850 | static sal_uInt16 Get_UShort( sal_uInt8 *& p ) | ||||||
851 | { | ||||||
852 | const sal_uInt16 n = SVBT16ToUInt16( *reinterpret_cast<SVBT16*>(p) ); | ||||||
853 | p += 2; | ||||||
854 | return n; | ||||||
855 | } | ||||||
856 | |||||||
857 | static sal_Int16 Get_Short( sal_uInt8 *& p ) | ||||||
858 | { | ||||||
859 | return Get_UShort(p); | ||||||
860 | } | ||||||
861 | |||||||
862 | static sal_uInt32 Get_ULong( sal_uInt8 *& p ) | ||||||
863 | { | ||||||
864 | sal_uInt32 n = SVBT32ToUInt32( *reinterpret_cast<SVBT32*>(p) ); | ||||||
865 | p += 4; | ||||||
866 | return n; | ||||||
867 | } | ||||||
868 | |||||||
869 | static sal_Int32 Get_Long( sal_uInt8 *& p ) | ||||||
870 | { | ||||||
871 | return Get_ULong(p); | ||||||
872 | } | ||||||
873 | |||||||
874 | WW8SprmIter::WW8SprmIter(const sal_uInt8* pSprms_, sal_Int32 nLen_, | ||||||
875 | const wwSprmParser &rParser) | ||||||
876 | : mrSprmParser(rParser), pSprms( pSprms_), nRemLen( nLen_) | ||||||
877 | { | ||||||
878 | UpdateMyMembers(); | ||||||
879 | } | ||||||
880 | |||||||
881 | void WW8SprmIter::SetSprms(const sal_uInt8* pSprms_, sal_Int32 nLen_) | ||||||
882 | { | ||||||
883 | pSprms = pSprms_; | ||||||
884 | nRemLen = nLen_; | ||||||
885 | UpdateMyMembers(); | ||||||
886 | } | ||||||
887 | |||||||
888 | void WW8SprmIter::advance() | ||||||
889 | { | ||||||
890 | if (nRemLen > 0 ) | ||||||
891 | { | ||||||
892 | sal_uInt16 nSize = nCurrentSize; | ||||||
893 | if (nSize > nRemLen) | ||||||
894 | nSize = nRemLen; | ||||||
895 | pSprms += nSize; | ||||||
896 | nRemLen -= nSize; | ||||||
897 | UpdateMyMembers(); | ||||||
898 | } | ||||||
899 | } | ||||||
900 | |||||||
901 | void WW8SprmIter::UpdateMyMembers() | ||||||
902 | { | ||||||
903 | bool bValid = (pSprms && nRemLen >= mrSprmParser.MinSprmLen()); | ||||||
904 | |||||||
905 | if (bValid) | ||||||
906 | { | ||||||
907 | nCurrentId = mrSprmParser.GetSprmId(pSprms); | ||||||
908 | nCurrentSize = mrSprmParser.GetSprmSize(nCurrentId, pSprms, nRemLen); | ||||||
909 | pCurrentParams = pSprms + mrSprmParser.DistanceToData(nCurrentId); | ||||||
910 | bValid = nCurrentSize <= nRemLen; | ||||||
911 | SAL_WARN_IF(!bValid, "sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong")do { if (true && (!bValid)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "911" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "911" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "911" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "911" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
912 | } | ||||||
913 | |||||||
914 | if (!bValid) | ||||||
915 | { | ||||||
916 | nCurrentId = 0; | ||||||
917 | pCurrentParams = nullptr; | ||||||
918 | nCurrentSize = 0; | ||||||
919 | nRemLen = 0; | ||||||
920 | } | ||||||
921 | } | ||||||
922 | |||||||
923 | SprmResult WW8SprmIter::FindSprm(sal_uInt16 nId, bool bFindFirst, const sal_uInt8* pNextByteMatch) | ||||||
924 | { | ||||||
925 | SprmResult aRet; | ||||||
926 | |||||||
927 | while (GetSprms()) | ||||||
928 | { | ||||||
929 | if (GetCurrentId() == nId) | ||||||
930 | { | ||||||
931 | sal_Int32 nFixedLen = mrSprmParser.DistanceToData(nId); | ||||||
932 | sal_Int32 nL = mrSprmParser.GetSprmSize(nId, GetSprms(), GetRemLen()); | ||||||
933 | SprmResult aSprmResult(GetCurrentParams(), nL - nFixedLen); | ||||||
934 | // typically pNextByteMatch is nullptr and we just return the first match | ||||||
935 | // very occasionally we want one with a specific following byte | ||||||
936 | if ( !pNextByteMatch || (aSprmResult.nRemainingData >= 1 && *aSprmResult.pSprm == *pNextByteMatch) ) | ||||||
937 | { | ||||||
938 | if ( bFindFirst ) | ||||||
939 | return aSprmResult; | ||||||
940 | aRet = aSprmResult; | ||||||
941 | } | ||||||
942 | } | ||||||
943 | advance(); | ||||||
944 | } | ||||||
945 | |||||||
946 | return aRet; | ||||||
947 | } | ||||||
948 | |||||||
949 | // temporary test | ||||||
950 | // WW8PLCFx_PCDAttrs cling to WW8PLCF_Pcd and therefore do not have their own iterators. | ||||||
951 | // All methods relating to iterators are therefore dummies. | ||||||
952 | WW8PLCFx_PCDAttrs::WW8PLCFx_PCDAttrs(const WW8Fib& rFib, | ||||||
953 | WW8PLCFx_PCD* pPLCFx_PCD, const WW8ScannerBase* pBase) | ||||||
954 | : WW8PLCFx(rFib, true), pPcdI(pPLCFx_PCD->GetPLCFIter()), | ||||||
955 | pPcd(pPLCFx_PCD), mrGrpprls(pBase->m_aPieceGrpprls) | ||||||
956 | { | ||||||
957 | } | ||||||
958 | |||||||
959 | sal_uInt32 WW8PLCFx_PCDAttrs::GetIdx() const | ||||||
960 | { | ||||||
961 | return 0; | ||||||
962 | } | ||||||
963 | |||||||
964 | void WW8PLCFx_PCDAttrs::SetIdx(sal_uInt32) | ||||||
965 | { | ||||||
966 | } | ||||||
967 | |||||||
968 | bool WW8PLCFx_PCDAttrs::SeekPos(WW8_CP ) | ||||||
969 | { | ||||||
970 | return true; | ||||||
971 | } | ||||||
972 | |||||||
973 | void WW8PLCFx_PCDAttrs::advance() | ||||||
974 | { | ||||||
975 | } | ||||||
976 | |||||||
977 | WW8_CP WW8PLCFx_PCDAttrs::Where() | ||||||
978 | { | ||||||
979 | return pPcd ? pPcd->Where() : WW8_CP_MAX; | ||||||
980 | } | ||||||
981 | |||||||
982 | void WW8PLCFx_PCDAttrs::GetSprms(WW8PLCFxDesc* p) | ||||||
983 | { | ||||||
984 | void* pData; | ||||||
985 | |||||||
986 | p->bRealLineEnd = false; | ||||||
987 | if ( !pPcdI || !pPcdI->Get(p->nStartPos, p->nEndPos, pData) ) | ||||||
988 | { | ||||||
989 | // PLCF fully processed | ||||||
990 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
991 | p->pMemPos = nullptr; | ||||||
992 | p->nSprmsLen = 0; | ||||||
993 | return; | ||||||
994 | } | ||||||
995 | |||||||
996 | const sal_uInt16 nPrm = SVBT16ToUInt16( static_cast<WW8_PCD*>(pData)->prm ); | ||||||
997 | if ( nPrm & 1 ) | ||||||
998 | { | ||||||
999 | // PRM Variant 2 | ||||||
1000 | const sal_uInt16 nSprmIdx = nPrm >> 1; | ||||||
1001 | |||||||
1002 | if( nSprmIdx >= mrGrpprls.size() ) | ||||||
1003 | { | ||||||
1004 | // Invalid Index | ||||||
1005 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
1006 | p->pMemPos = nullptr; | ||||||
1007 | p->nSprmsLen = 0; | ||||||
1008 | return; | ||||||
1009 | } | ||||||
1010 | const sal_uInt8* pSprms = mrGrpprls[ nSprmIdx ].get(); | ||||||
1011 | |||||||
1012 | p->nSprmsLen = SVBT16ToUInt16( pSprms ); // Length | ||||||
1013 | pSprms += 2; | ||||||
1014 | p->pMemPos = pSprms; // Position | ||||||
1015 | } | ||||||
1016 | else | ||||||
1017 | { | ||||||
1018 | // SPRM is stored directly into members var | ||||||
1019 | /* | ||||||
1020 | These are the attr that are in the piece-table instead of in the text! | ||||||
1021 | */ | ||||||
1022 | |||||||
1023 | if (IsSevenMinus(GetFIBVersion())) | ||||||
1024 | { | ||||||
1025 | aShortSprm[0] = static_cast<sal_uInt8>( ( nPrm & 0xfe) >> 1 ); | ||||||
1026 | aShortSprm[1] = static_cast<sal_uInt8>( nPrm >> 8 ); | ||||||
1027 | p->nSprmsLen = nPrm ? 2 : 0; // length | ||||||
1028 | |||||||
1029 | // store Position of internal mini storage in Data Pointer | ||||||
1030 | p->pMemPos = aShortSprm; | ||||||
1031 | } | ||||||
1032 | else | ||||||
1033 | { | ||||||
1034 | p->pMemPos = nullptr; | ||||||
1035 | p->nSprmsLen = 0; | ||||||
1036 | sal_uInt8 nSprmListIdx = static_cast<sal_uInt8>((nPrm & 0xfe) >> 1); | ||||||
1037 | if( nSprmListIdx ) | ||||||
1038 | { | ||||||
1039 | // process Sprm Id Matching as explained in MS Documentation | ||||||
1040 | |||||||
1041 | // ''Property Modifier(variant 1) (PRM)'' | ||||||
1042 | // see file: s62f39.htm | ||||||
1043 | |||||||
1044 | // Since Sprm is 7 bits, rgsprmPrm can hold 0x80 entries. | ||||||
1045 | static const sal_uInt16 aSprmId[0x80] = | ||||||
1046 | { | ||||||
1047 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop | ||||||
1048 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1049 | // sprmPIncLvl, sprmPJc, sprmPFSideBySide, sprmPFKeep | ||||||
1050 | 0x2402,0x2403,NS_sprm::LN_PFSideBySide,0x2405, | ||||||
1051 | // sprmPFKeepFollow, sprmPFPageBreakBefore, sprmPBrcl, | ||||||
1052 | // sprmPBrcp | ||||||
1053 | 0x2406,0x2407,NS_sprm::LN_PBrcl,NS_sprm::LN_PBrcp, | ||||||
1054 | // sprmPIlvl, sprmNoop, sprmPFNoLineNumb, sprmNoop | ||||||
1055 | 0x260A,0x0000,0x240C,0x0000, | ||||||
1056 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop | ||||||
1057 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1058 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop | ||||||
1059 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1060 | // sprmPFInTable, sprmPFTtp, sprmNoop, sprmNoop | ||||||
1061 | 0x2416,0x2417,0x0000,0x0000, | ||||||
1062 | // sprmNoop, sprmPPc, sprmNoop, sprmNoop | ||||||
1063 | 0x0000,0x261B,0x0000,0x0000, | ||||||
1064 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop | ||||||
1065 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1066 | // sprmNoop, sprmPWr, sprmNoop, sprmNoop | ||||||
1067 | 0x0000,0x2423,0x0000,0x0000, | ||||||
1068 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop | ||||||
1069 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1070 | // sprmPFNoAutoHyph, sprmNoop, sprmNoop, sprmNoop | ||||||
1071 | 0x242A,0x0000,0x0000,0x0000, | ||||||
1072 | // sprmNoop, sprmNoop, sprmPFLocked, sprmPFWidowControl | ||||||
1073 | 0x0000,0x0000,0x2430,0x2431, | ||||||
1074 | // sprmNoop, sprmPFKinsoku, sprmPFWordWrap, | ||||||
1075 | // sprmPFOverflowPunct | ||||||
1076 | 0x0000,0x2433,0x2434,0x2435, | ||||||
1077 | // sprmPFTopLinePunct, sprmPFAutoSpaceDE, | ||||||
1078 | // sprmPFAutoSpaceDN, sprmNoop | ||||||
1079 | 0x2436,0x2437,0x2438,0x0000, | ||||||
1080 | // sprmNoop, sprmPISnapBaseLine, sprmNoop, sprmNoop | ||||||
1081 | 0x0000,NS_sprm::LN_PISnapBaseLine,0x000,0x0000, | ||||||
1082 | // sprmNoop, sprmCFStrikeRM, sprmCFRMark, sprmCFFieldVanish | ||||||
1083 | 0x0000,0x0800,0x0801,0x0802, | ||||||
1084 | // sprmNoop, sprmNoop, sprmNoop, sprmCFData | ||||||
1085 | 0x0000,0x0000,0x0000,0x0806, | ||||||
1086 | // sprmNoop, sprmNoop, sprmNoop, sprmCFOle2 | ||||||
1087 | 0x0000,0x0000,0x0000,0x080A, | ||||||
1088 | // sprmNoop, sprmCHighlight, sprmCFEmboss, sprmCSfxText | ||||||
1089 | 0x0000,0x2A0C,0x0858,0x2859, | ||||||
1090 | // sprmNoop, sprmNoop, sprmNoop, sprmCPlain | ||||||
1091 | 0x0000,0x0000,0x0000,0x2A33, | ||||||
1092 | // sprmNoop, sprmCFBold, sprmCFItalic, sprmCFStrike | ||||||
1093 | 0x0000,0x0835,0x0836,0x0837, | ||||||
1094 | // sprmCFOutline, sprmCFShadow, sprmCFSmallCaps, sprmCFCaps, | ||||||
1095 | 0x0838,0x0839,0x083a,0x083b, | ||||||
1096 | // sprmCFVanish, sprmNoop, sprmCKul, sprmNoop, | ||||||
1097 | 0x083C,0x0000,0x2A3E,0x0000, | ||||||
1098 | // sprmNoop, sprmNoop, sprmCIco, sprmNoop, | ||||||
1099 | 0x0000,0x0000,0x2A42,0x0000, | ||||||
1100 | // sprmCHpsInc, sprmNoop, sprmCHpsPosAdj, sprmNoop, | ||||||
1101 | NS_sprm::LN_CHpsInc,0x0000,NS_sprm::LN_CHpsPosAdj,0x0000, | ||||||
1102 | // sprmCIss, sprmNoop, sprmNoop, sprmNoop, | ||||||
1103 | 0x2A48,0x0000,0x0000,0x0000, | ||||||
1104 | // sprmNoop, sprmNoop, sprmNoop, sprmNoop, | ||||||
1105 | 0x0000,0x0000,0x0000,0x0000, | ||||||
1106 | // sprmNoop, sprmNoop, sprmNoop, sprmCFDStrike, | ||||||
1107 | 0x0000,0x0000,0x0000,0x2A53, | ||||||
1108 | // sprmCFImprint, sprmCFSpec, sprmCFObj, sprmPicBrcl, | ||||||
1109 | 0x0854,0x0855,0x0856,NS_sprm::LN_PicBrcl, | ||||||
1110 | // sprmPOutLvl, sprmPFBiDi, sprmNoop, sprmNoop, | ||||||
1111 | 0x2640,0x2441,0x0000,0x0000, | ||||||
1112 | // sprmNoop, sprmNoop, sprmPPnbrRMarkNot | ||||||
1113 | 0x0000,0x0000,0x0000,0x0000 | ||||||
1114 | }; | ||||||
1115 | |||||||
1116 | // find real Sprm Id: | ||||||
1117 | const sal_uInt16 nSprmId = aSprmId[ nSprmListIdx ]; | ||||||
1118 | |||||||
1119 | if( nSprmId ) | ||||||
1120 | { | ||||||
1121 | // move Sprm Id and Sprm Param to internal mini storage: | ||||||
1122 | aShortSprm[0] = static_cast<sal_uInt8>( nSprmId & 0x00ff) ; | ||||||
1123 | aShortSprm[1] = static_cast<sal_uInt8>( ( nSprmId & 0xff00) >> 8 ); | ||||||
1124 | aShortSprm[2] = static_cast<sal_uInt8>( nPrm >> 8 ); | ||||||
1125 | |||||||
1126 | // store Sprm Length in member: | ||||||
1127 | p->nSprmsLen = nPrm ? 3 : 0; | ||||||
1128 | |||||||
1129 | // store Position of internal mini storage in Data Pointer | ||||||
1130 | p->pMemPos = aShortSprm; | ||||||
1131 | } | ||||||
1132 | } | ||||||
1133 | } | ||||||
1134 | } | ||||||
1135 | } | ||||||
1136 | |||||||
1137 | WW8PLCFx_PCD::WW8PLCFx_PCD(const WW8Fib& rFib, WW8PLCFpcd* pPLCFpcd, | ||||||
1138 | WW8_CP nStartCp, bool bVer67P) | ||||||
1139 | : WW8PLCFx(rFib, false), nClipStart(-1) | ||||||
1140 | { | ||||||
1141 | // construct own iterator | ||||||
1142 | pPcdI.reset( new WW8PLCFpcd_Iter(*pPLCFpcd, nStartCp) ); | ||||||
1143 | bVer67= bVer67P; | ||||||
1144 | } | ||||||
1145 | |||||||
1146 | WW8PLCFx_PCD::~WW8PLCFx_PCD() | ||||||
1147 | { | ||||||
1148 | } | ||||||
1149 | |||||||
1150 | sal_uInt32 WW8PLCFx_PCD::GetIMax() const | ||||||
1151 | { | ||||||
1152 | return pPcdI ? pPcdI->GetIMax() : 0; | ||||||
1153 | } | ||||||
1154 | |||||||
1155 | sal_uInt32 WW8PLCFx_PCD::GetIdx() const | ||||||
1156 | { | ||||||
1157 | return pPcdI ? pPcdI->GetIdx() : 0; | ||||||
1158 | } | ||||||
1159 | |||||||
1160 | void WW8PLCFx_PCD::SetIdx(sal_uInt32 nIdx) | ||||||
1161 | { | ||||||
1162 | if (pPcdI) | ||||||
1163 | pPcdI->SetIdx( nIdx ); | ||||||
1164 | } | ||||||
1165 | |||||||
1166 | bool WW8PLCFx_PCD::SeekPos(WW8_CP nCpPos) | ||||||
1167 | { | ||||||
1168 | return pPcdI && pPcdI->SeekPos( nCpPos ); | ||||||
1169 | } | ||||||
1170 | |||||||
1171 | WW8_CP WW8PLCFx_PCD::Where() | ||||||
1172 | { | ||||||
1173 | return pPcdI ? pPcdI->Where() : WW8_CP_MAX; | ||||||
1174 | } | ||||||
1175 | |||||||
1176 | long WW8PLCFx_PCD::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) | ||||||
1177 | { | ||||||
1178 | void* pData; | ||||||
1179 | rLen = 0; | ||||||
1180 | |||||||
1181 | if ( !pPcdI || !pPcdI->Get(rStart, rEnd, pData) ) | ||||||
1182 | { | ||||||
1183 | rStart = rEnd = WW8_CP_MAX; | ||||||
1184 | return -1; | ||||||
1185 | } | ||||||
1186 | return pPcdI->GetIdx(); | ||||||
1187 | } | ||||||
1188 | |||||||
1189 | void WW8PLCFx_PCD::advance() | ||||||
1190 | { | ||||||
1191 | OSL_ENSURE(pPcdI , "missing pPcdI")do { if (true && (!(pPcdI))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1191" ": "), "%s", "missing pPcdI"); } } while (false); | ||||||
1192 | if (pPcdI) | ||||||
1193 | pPcdI->advance(); | ||||||
1194 | } | ||||||
1195 | |||||||
1196 | WW8_FC WW8PLCFx_PCD::CurrentPieceStartCp2Fc( WW8_CP nCp ) | ||||||
1197 | { | ||||||
1198 | WW8_CP nCpStart, nCpEnd; | ||||||
1199 | void* pData; | ||||||
1200 | |||||||
1201 | if ( !pPcdI->Get(nCpStart, nCpEnd, pData) ) | ||||||
1202 | { | ||||||
1203 | OSL_ENSURE( false, "CurrentPieceStartCp2Fc() with false Cp found (1)" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1203" ": "), "%s", "CurrentPieceStartCp2Fc() with false Cp found (1)" ); } } while (false); | ||||||
1204 | return WW8_FC_MAX; | ||||||
1205 | } | ||||||
1206 | |||||||
1207 | OSL_ENSURE( nCp >= nCpStart && nCp < nCpEnd,do { if (true && (!(nCp >= nCpStart && nCp < nCpEnd))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1208" ": "), "%s", "AktPieceCp2Fc() with false Cp found (2)" ); } } while (false) | ||||||
1208 | "AktPieceCp2Fc() with false Cp found (2)" )do { if (true && (!(nCp >= nCpStart && nCp < nCpEnd))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1208" ": "), "%s", "AktPieceCp2Fc() with false Cp found (2)" ); } } while (false); | ||||||
1209 | |||||||
1210 | if( nCp < nCpStart ) | ||||||
1211 | nCp = nCpStart; | ||||||
1212 | if( nCp >= nCpEnd ) | ||||||
1213 | nCp = nCpEnd - 1; | ||||||
1214 | |||||||
1215 | bool bIsUnicode = false; | ||||||
1216 | WW8_FC nFC = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc ); | ||||||
1217 | if( !bVer67 ) | ||||||
1218 | nFC = WW8PLCFx_PCD::TransformPieceAddress( nFC, bIsUnicode ); | ||||||
1219 | |||||||
1220 | WW8_CP nDistance; | ||||||
1221 | bool bFail = o3tl::checked_sub(nCp, nCpStart, nDistance); | ||||||
1222 | if (bFail) | ||||||
1223 | { | ||||||
1224 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1224" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1224" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1224" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1224" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1225 | return WW8_FC_MAX; | ||||||
1226 | } | ||||||
1227 | |||||||
1228 | if (bIsUnicode) | ||||||
1229 | { | ||||||
1230 | bFail = o3tl::checked_multiply<WW8_CP>(nDistance, 2, nDistance); | ||||||
1231 | if (bFail) | ||||||
1232 | { | ||||||
1233 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1233" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1233" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1233" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1233" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1234 | return WW8_FC_MAX; | ||||||
1235 | } | ||||||
1236 | } | ||||||
1237 | |||||||
1238 | WW8_FC nRet; | ||||||
1239 | bFail = o3tl::checked_add(nFC, nDistance, nRet); | ||||||
1240 | if (bFail) | ||||||
1241 | { | ||||||
1242 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1242" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1242" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1242" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1242" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1243 | return WW8_FC_MAX; | ||||||
1244 | } | ||||||
1245 | |||||||
1246 | return nRet; | ||||||
1247 | } | ||||||
1248 | |||||||
1249 | void WW8PLCFx_PCD::CurrentPieceFc2Cp( WW8_CP& rStartPos, WW8_CP& rEndPos, | ||||||
1250 | const WW8ScannerBase *pSBase ) | ||||||
1251 | { | ||||||
1252 | //No point going anywhere with this | ||||||
1253 | if ((rStartPos == WW8_CP_MAX) && (rEndPos == WW8_CP_MAX)) | ||||||
1254 | return; | ||||||
1255 | |||||||
1256 | rStartPos = pSBase->WW8Fc2Cp( rStartPos ); | ||||||
1257 | rEndPos = pSBase->WW8Fc2Cp( rEndPos ); | ||||||
1258 | } | ||||||
1259 | |||||||
1260 | WW8_CP WW8PLCFx_PCD::CurrentPieceStartFc2Cp( WW8_FC nStartPos ) | ||||||
1261 | { | ||||||
1262 | WW8_CP nCpStart, nCpEnd; | ||||||
1263 | void* pData; | ||||||
1264 | if ( !pPcdI->Get( nCpStart, nCpEnd, pData ) ) | ||||||
1265 | { | ||||||
1266 | OSL_ENSURE( false, "CurrentPieceStartFc2Cp() - error" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1266" ": "), "%s", "CurrentPieceStartFc2Cp() - error"); } } while (false); | ||||||
1267 | return WW8_CP_MAX; | ||||||
1268 | } | ||||||
1269 | bool bIsUnicode = false; | ||||||
1270 | sal_Int32 nFcStart = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc ); | ||||||
1271 | if( !bVer67 ) | ||||||
1272 | nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, bIsUnicode ); | ||||||
1273 | |||||||
1274 | sal_Int32 nUnicodeFactor = bIsUnicode ? 2 : 1; | ||||||
1275 | |||||||
1276 | if( nStartPos < nFcStart ) | ||||||
1277 | nStartPos = nFcStart; | ||||||
1278 | |||||||
1279 | WW8_CP nCpLen; | ||||||
1280 | bool bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen); | ||||||
1281 | if (bFail) | ||||||
1282 | { | ||||||
1283 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1283" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1283" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1283" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1283" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1284 | return WW8_CP_MAX; | ||||||
1285 | } | ||||||
1286 | |||||||
1287 | WW8_CP nCpLenBytes; | ||||||
1288 | bFail = o3tl::checked_multiply(nCpLen, nUnicodeFactor, nCpLenBytes); | ||||||
1289 | if (bFail) | ||||||
1290 | { | ||||||
1291 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1291" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1291" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1291" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1291" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1292 | return WW8_CP_MAX; | ||||||
1293 | } | ||||||
1294 | |||||||
1295 | WW8_FC nFcLen; | ||||||
1296 | bFail = o3tl::checked_add(nFcStart, nCpLenBytes, nFcLen); | ||||||
1297 | if (bFail) | ||||||
1298 | { | ||||||
1299 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1299" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1299" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1299" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1299" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1300 | return WW8_CP_MAX; | ||||||
1301 | } | ||||||
1302 | |||||||
1303 | WW8_FC nFcEnd; | ||||||
1304 | bFail = o3tl::checked_add(nFcStart, nFcLen, nFcEnd); | ||||||
1305 | if (bFail) | ||||||
1306 | { | ||||||
1307 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1307" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1307" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1307" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1307" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1308 | return WW8_CP_MAX; | ||||||
1309 | } | ||||||
1310 | |||||||
1311 | |||||||
1312 | if (nStartPos >= nFcEnd) | ||||||
1313 | nStartPos = nFcEnd - (1 * nUnicodeFactor); | ||||||
1314 | |||||||
1315 | WW8_FC nFcDiff = (nStartPos - nFcStart) / nUnicodeFactor; | ||||||
1316 | |||||||
1317 | WW8_FC nCpRet; | ||||||
1318 | bFail = o3tl::checked_add(nCpStart, nFcDiff, nCpRet); | ||||||
1319 | if (bFail) | ||||||
1320 | { | ||||||
1321 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1321" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1321" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1321" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1321" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1322 | return WW8_CP_MAX; | ||||||
1323 | } | ||||||
1324 | |||||||
1325 | return nCpRet; | ||||||
1326 | } | ||||||
1327 | |||||||
1328 | // Helper routines for all | ||||||
1329 | |||||||
1330 | // Convert BRC from WW6 to WW8 format | ||||||
1331 | WW8_BRC::WW8_BRC(const WW8_BRCVer6& brcVer6) | ||||||
1332 | { | ||||||
1333 | sal_uInt8 _dptLineWidth = brcVer6.dxpLineWidth(), | ||||||
1334 | _brcType = brcVer6.brcType(); | ||||||
1335 | |||||||
1336 | if (_dptLineWidth > 5) // this signifies dashed(6) or dotted(7) line | ||||||
1337 | { | ||||||
1338 | _brcType = _dptLineWidth; | ||||||
1339 | _dptLineWidth = 1; | ||||||
1340 | } | ||||||
1341 | _dptLineWidth *= 6; // convert units from 0.75pt to 1/8pt | ||||||
1342 | |||||||
1343 | *this = WW8_BRC(_dptLineWidth, _brcType, brcVer6.ico(), brcVer6.dxpSpace(), | ||||||
1344 | brcVer6.fShadow(), false); | ||||||
1345 | } | ||||||
1346 | |||||||
1347 | // Convert BRC from WW8 to WW9 format | ||||||
1348 | WW8_BRCVer9::WW8_BRCVer9(const WW8_BRC& brcVer8) | ||||||
1349 | { | ||||||
1350 | if (brcVer8.isNil()) { | ||||||
1351 | UInt32ToSVBT32(0, aBits1); | ||||||
1352 | UInt32ToSVBT32(0xffffffff, aBits2); | ||||||
1353 | } | ||||||
1354 | else | ||||||
1355 | { | ||||||
1356 | sal_uInt32 _cv = brcVer8.ico() == 0 ? 0xff000000 // "auto" colour | ||||||
1357 | : wwUtility::RGBToBGR(SwWW8ImplReader::GetCol(brcVer8.ico())); | ||||||
1358 | *this = WW8_BRCVer9(_cv, brcVer8.dptLineWidth(), brcVer8.brcType(), | ||||||
1359 | brcVer8.dptSpace(), brcVer8.fShadow(), brcVer8.fFrame()); | ||||||
1360 | } | ||||||
1361 | } | ||||||
1362 | |||||||
1363 | short WW8_BRC::DetermineBorderProperties(short *pSpace) const | ||||||
1364 | { | ||||||
1365 | WW8_BRCVer9 brcVer9(*this); | ||||||
1366 | return brcVer9.DetermineBorderProperties(pSpace); | ||||||
1367 | } | ||||||
1368 | |||||||
1369 | short WW8_BRCVer9::DetermineBorderProperties(short *pSpace) const | ||||||
1370 | { | ||||||
1371 | /* | ||||||
1372 | Word does not factor the width of the border into the width/height | ||||||
1373 | stored in the information for graphic/table/object widths, so we need | ||||||
1374 | to figure out this extra width here and utilize the returned size in | ||||||
1375 | our calculations | ||||||
1376 | */ | ||||||
1377 | short nMSTotalWidth; | ||||||
1378 | |||||||
1379 | //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5 | ||||||
1380 | nMSTotalWidth = static_cast<short>(dptLineWidth()) * 20 / 8; | ||||||
1381 | |||||||
1382 | //Figure out the real size of the border according to word | ||||||
1383 | switch (brcType()) | ||||||
1384 | { | ||||||
1385 | //Note that codes over 25 are undocumented, and I can't create | ||||||
1386 | //these 4 here in the wild. | ||||||
1387 | case 2: | ||||||
1388 | case 4: | ||||||
1389 | case 5: | ||||||
1390 | case 22: | ||||||
1391 | OSL_FAIL("Can't create these from the menus, please report")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1391" ": "), "%s", "Can't create these from the menus, please report" ); } } while (false); | ||||||
1392 | break; | ||||||
1393 | default: | ||||||
1394 | case 23: //Only 3pt in the menus, but honours the size setting. | ||||||
1395 | break; | ||||||
1396 | case 10: | ||||||
1397 | /* | ||||||
1398 | triple line is five times the width of an ordinary line, | ||||||
1399 | except that the smallest 1/4 point size appears to have | ||||||
1400 | exactly the same total border width as a 3/4 point size | ||||||
1401 | ordinary line, i.e. three times the nominal line width. The | ||||||
1402 | second smallest 1/2 point size appears to have exactly the | ||||||
1403 | total border width as a 2 1/4 border, i.e 4.5 times the size. | ||||||
1404 | */ | ||||||
1405 | if (nMSTotalWidth == 5) | ||||||
1406 | nMSTotalWidth*=3; | ||||||
1407 | else if (nMSTotalWidth == 10) | ||||||
1408 | nMSTotalWidth = nMSTotalWidth*9/2; | ||||||
1409 | else | ||||||
1410 | nMSTotalWidth*=5; | ||||||
1411 | break; | ||||||
1412 | case 20: | ||||||
1413 | /* | ||||||
1414 | wave, the dimensions appear to be created by the drawing of | ||||||
1415 | the wave, so we have only two possibilities in the menus, 3/4 | ||||||
1416 | point is equal to solid 3 point. This calculation seems to | ||||||
1417 | match well to results. | ||||||
1418 | */ | ||||||
1419 | nMSTotalWidth +=45; | ||||||
1420 | break; | ||||||
1421 | case 21: | ||||||
1422 | /* | ||||||
1423 | double wave, the dimensions appear to be created by the | ||||||
1424 | drawing of the wave, so we have only one possibilities in the | ||||||
1425 | menus, that of 3/4 point is equal to solid 3 point. This | ||||||
1426 | calculation seems to match well to results. | ||||||
1427 | */ | ||||||
1428 | nMSTotalWidth += 45*2; | ||||||
1429 | break; | ||||||
1430 | } | ||||||
1431 | |||||||
1432 | if (pSpace) | ||||||
1433 | *pSpace = static_cast<short>(dptSpace()) * 20; // convert from points to twips | ||||||
1434 | return nMSTotalWidth; | ||||||
1435 | } | ||||||
1436 | |||||||
1437 | /* | ||||||
1438 | * WW8Cp2Fc is a good method, a CP always maps to a FC | ||||||
1439 | * WW8Fc2Cp on the other hand is more dubious, a random FC | ||||||
1440 | * may not map to a valid CP. Try and avoid WW8Fc2Cp where | ||||||
1441 | * possible | ||||||
1442 | */ | ||||||
1443 | WW8_CP WW8ScannerBase::WW8Fc2Cp( WW8_FC nFcPos ) const | ||||||
1444 | { | ||||||
1445 | WW8_CP nFallBackCpEnd = WW8_CP_MAX; | ||||||
1446 | if( nFcPos == WW8_FC_MAX ) | ||||||
1447 | return nFallBackCpEnd; | ||||||
1448 | |||||||
1449 | bool bIsUnicode; | ||||||
1450 | if (m_pWw8Fib->m_nVersion >= 8) | ||||||
1451 | bIsUnicode = false; | ||||||
1452 | else | ||||||
1453 | bIsUnicode = m_pWw8Fib->m_fExtChar; | ||||||
1454 | |||||||
1455 | if( m_pPieceIter ) // Complex File ? | ||||||
1456 | { | ||||||
1457 | sal_uInt32 nOldPos = m_pPieceIter->GetIdx(); | ||||||
1458 | |||||||
1459 | for (m_pPieceIter->SetIdx(0); | ||||||
1460 | m_pPieceIter->GetIdx() < m_pPieceIter->GetIMax(); m_pPieceIter->advance()) | ||||||
1461 | { | ||||||
1462 | WW8_CP nCpStart, nCpEnd; | ||||||
1463 | void* pData; | ||||||
1464 | if( !m_pPieceIter->Get( nCpStart, nCpEnd, pData ) ) | ||||||
1465 | { // outside PLCFfpcd ? | ||||||
1466 | OSL_ENSURE( false, "PLCFpcd-WW8Fc2Cp() went wrong" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1466" ": "), "%s", "PLCFpcd-WW8Fc2Cp() went wrong"); } } while (false); | ||||||
1467 | break; | ||||||
1468 | } | ||||||
1469 | sal_Int32 nFcStart = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc ); | ||||||
1470 | if (m_pWw8Fib->m_nVersion >= 8) | ||||||
1471 | { | ||||||
1472 | nFcStart = WW8PLCFx_PCD::TransformPieceAddress( nFcStart, | ||||||
1473 | bIsUnicode ); | ||||||
1474 | } | ||||||
1475 | else | ||||||
1476 | { | ||||||
1477 | bIsUnicode = m_pWw8Fib->m_fExtChar; | ||||||
1478 | } | ||||||
1479 | |||||||
1480 | sal_Int32 nLen; | ||||||
1481 | if (o3tl::checked_sub(nCpEnd, nCpStart, nLen)) | ||||||
1482 | { | ||||||
1483 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1483" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1483" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1483" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1483" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1484 | return WW8_CP_MAX; | ||||||
1485 | } | ||||||
1486 | if (bIsUnicode) | ||||||
1487 | { | ||||||
1488 | if (o3tl::checked_multiply<WW8_CP>(nLen, 2, nLen)) | ||||||
1489 | { | ||||||
1490 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1490" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1490" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1490" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1490" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1491 | return WW8_CP_MAX; | ||||||
1492 | } | ||||||
1493 | } | ||||||
1494 | |||||||
1495 | /* | ||||||
1496 | If this cp is inside this piece, or it's the last piece and we are | ||||||
1497 | on the very last cp of that piece | ||||||
1498 | */ | ||||||
1499 | if (nFcPos >= nFcStart) | ||||||
1500 | { | ||||||
1501 | // found | ||||||
1502 | WW8_FC nFcDiff; | ||||||
1503 | if (o3tl::checked_sub(nFcPos, nFcStart, nFcDiff)) | ||||||
1504 | { | ||||||
1505 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1505" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1505" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1505" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1505" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1506 | return WW8_CP_MAX; | ||||||
1507 | } | ||||||
1508 | if (bIsUnicode) | ||||||
1509 | nFcDiff /= 2; | ||||||
1510 | WW8_CP nTempCp; | ||||||
1511 | if (o3tl::checked_add(nCpStart, nFcDiff, nTempCp)) | ||||||
1512 | { | ||||||
1513 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1513" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1513" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1513" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1513" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1514 | return WW8_CP_MAX; | ||||||
1515 | } | ||||||
1516 | WW8_FC nFcEnd; | ||||||
1517 | if (o3tl::checked_add(nFcStart, nLen, nFcEnd)) | ||||||
1518 | { | ||||||
1519 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1519" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1519" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1519" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1519" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1520 | return WW8_CP_MAX; | ||||||
1521 | } | ||||||
1522 | if (nFcPos < nFcEnd) | ||||||
1523 | { | ||||||
1524 | m_pPieceIter->SetIdx( nOldPos ); | ||||||
1525 | return nTempCp; | ||||||
1526 | } | ||||||
1527 | else if (nFcPos == nFcEnd) | ||||||
1528 | { | ||||||
1529 | //Keep this cp as its on a piece boundary because we might | ||||||
1530 | //need it if tests fail | ||||||
1531 | nFallBackCpEnd = nTempCp; | ||||||
1532 | } | ||||||
1533 | } | ||||||
1534 | } | ||||||
1535 | // not found | ||||||
1536 | m_pPieceIter->SetIdx( nOldPos ); // not found | ||||||
1537 | /* | ||||||
1538 | If it was not found, then this is because it has fallen between two | ||||||
1539 | stools, i.e. either it is the last cp/fc of the last piece, or it is | ||||||
1540 | the last cp/fc of a disjoint piece. | ||||||
1541 | */ | ||||||
1542 | return nFallBackCpEnd; | ||||||
1543 | } | ||||||
1544 | |||||||
1545 | WW8_FC nFcDiff; | ||||||
1546 | if (o3tl::checked_sub(nFcPos, m_pWw8Fib->m_fcMin, nFcDiff)) | ||||||
1547 | { | ||||||
1548 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1548" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1548" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1548" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1548" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1549 | return WW8_CP_MAX; | ||||||
1550 | } | ||||||
1551 | |||||||
1552 | // No complex file | ||||||
1553 | if (!bIsUnicode) | ||||||
1554 | nFallBackCpEnd = nFcDiff; | ||||||
1555 | else | ||||||
1556 | nFallBackCpEnd = (nFcDiff + 1) / 2; | ||||||
1557 | |||||||
1558 | return nFallBackCpEnd; | ||||||
1559 | } | ||||||
1560 | |||||||
1561 | // the fib of WinWord2 has a last entry of cpnBtePap of 2 byte sized type PN at | ||||||
1562 | // offset 324 | ||||||
1563 | const int nSmallestPossibleFib = 326; | ||||||
1564 | |||||||
1565 | WW8_FC WW8ScannerBase::WW8Cp2Fc(WW8_CP nCpPos, bool* pIsUnicode, | ||||||
1566 | WW8_CP* pNextPieceCp, bool* pTestFlag) const | ||||||
1567 | { | ||||||
1568 | if( pTestFlag ) | ||||||
1569 | *pTestFlag = true; | ||||||
1570 | if( WW8_CP_MAX == nCpPos ) | ||||||
1571 | return WW8_CP_MAX; | ||||||
1572 | |||||||
1573 | bool bIsUnicode; | ||||||
1574 | if( !pIsUnicode ) | ||||||
1575 | pIsUnicode = &bIsUnicode; | ||||||
1576 | |||||||
1577 | if (m_pWw8Fib->m_nVersion >= 8) | ||||||
1578 | *pIsUnicode = false; | ||||||
1579 | else | ||||||
1580 | *pIsUnicode = m_pWw8Fib->m_fExtChar; | ||||||
1581 | |||||||
1582 | WW8_FC nRet; | ||||||
1583 | |||||||
1584 | if( m_pPieceIter ) | ||||||
1585 | { | ||||||
1586 | // Complex File | ||||||
1587 | if( pNextPieceCp ) | ||||||
1588 | *pNextPieceCp = WW8_CP_MAX; | ||||||
1589 | |||||||
1590 | if( !m_pPieceIter->SeekPos( nCpPos ) ) | ||||||
1591 | { | ||||||
1592 | if( pTestFlag ) | ||||||
1593 | *pTestFlag = false; | ||||||
1594 | else { | ||||||
1595 | OSL_ENSURE( false, "Handed over wrong CP to WW8Cp2Fc()" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1595" ": "), "%s", "Handed over wrong CP to WW8Cp2Fc()" ); } } while (false); | ||||||
1596 | } | ||||||
1597 | return WW8_FC_MAX; | ||||||
1598 | } | ||||||
1599 | WW8_CP nCpStart, nCpEnd; | ||||||
1600 | void* pData; | ||||||
1601 | if( !m_pPieceIter->Get( nCpStart, nCpEnd, pData ) ) | ||||||
1602 | { | ||||||
1603 | if( pTestFlag ) | ||||||
1604 | *pTestFlag = false; | ||||||
1605 | else { | ||||||
1606 | OSL_ENSURE( false, "PLCFfpcd-Get went wrong" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1606" ": "), "%s", "PLCFfpcd-Get went wrong"); } } while (false); | ||||||
1607 | } | ||||||
1608 | return WW8_FC_MAX; | ||||||
1609 | } | ||||||
1610 | if( pNextPieceCp ) | ||||||
1611 | *pNextPieceCp = nCpEnd; | ||||||
1612 | |||||||
1613 | nRet = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc ); | ||||||
1614 | if (m_pWw8Fib->m_nVersion >= 8) | ||||||
1615 | nRet = WW8PLCFx_PCD::TransformPieceAddress( nRet, *pIsUnicode ); | ||||||
1616 | else | ||||||
1617 | *pIsUnicode = m_pWw8Fib->m_fExtChar; | ||||||
1618 | |||||||
1619 | WW8_CP nCpLen; | ||||||
1620 | bool bFail = o3tl::checked_sub(nCpPos, nCpStart, nCpLen); | ||||||
1621 | if (bFail) | ||||||
1622 | { | ||||||
1623 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1623" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1623" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1623" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1623" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1624 | return WW8_CP_MAX; | ||||||
1625 | } | ||||||
1626 | |||||||
1627 | if (*pIsUnicode) | ||||||
1628 | { | ||||||
1629 | bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen); | ||||||
1630 | if (bFail) | ||||||
1631 | { | ||||||
1632 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1632" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1632" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1632" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1632" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1633 | return WW8_CP_MAX; | ||||||
1634 | } | ||||||
1635 | } | ||||||
1636 | |||||||
1637 | bFail = o3tl::checked_add(nRet, nCpLen, nRet); | ||||||
1638 | if (bFail) | ||||||
1639 | { | ||||||
1640 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1640" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1640" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1640" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1640" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1641 | return WW8_CP_MAX; | ||||||
1642 | } | ||||||
1643 | |||||||
1644 | return nRet; | ||||||
1645 | } | ||||||
1646 | |||||||
1647 | if (*pIsUnicode) | ||||||
1648 | { | ||||||
1649 | const bool bFail = o3tl::checked_multiply<WW8_CP>(nCpPos, 2, nCpPos); | ||||||
1650 | if (bFail) | ||||||
1651 | { | ||||||
1652 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1652" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1652" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1652" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1652" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1653 | return WW8_CP_MAX; | ||||||
1654 | } | ||||||
1655 | } | ||||||
1656 | |||||||
1657 | // No complex file | ||||||
1658 | const bool bFail = o3tl::checked_add(m_pWw8Fib->m_fcMin, nCpPos, nRet); | ||||||
1659 | if (bFail) | ||||||
1660 | { | ||||||
1661 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1661" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1661" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1661" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1661" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1662 | return WW8_CP_MAX; | ||||||
1663 | } | ||||||
1664 | |||||||
1665 | // the text and the fib share the same stream, if the text is inside the fib | ||||||
1666 | // then it's definitely a bad offset. The smallest FIB supported is that of | ||||||
1667 | // WW2 which is 326 bytes in size | ||||||
1668 | if (nRet < nSmallestPossibleFib) | ||||||
1669 | { | ||||||
1670 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1670" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1670" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1670" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1670" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
1671 | return WW8_CP_MAX; | ||||||
1672 | } | ||||||
1673 | |||||||
1674 | return nRet; | ||||||
1675 | } | ||||||
1676 | |||||||
1677 | std::unique_ptr<WW8PLCFpcd> WW8ScannerBase::OpenPieceTable( SvStream* pStr, const WW8Fib* pWwF ) | ||||||
1678 | { | ||||||
1679 | if ( ((8 > m_pWw8Fib->m_nVersion) && !pWwF->m_fComplex) || !pWwF->m_lcbClx ) | ||||||
1680 | return nullptr; | ||||||
1681 | |||||||
1682 | if (pWwF->m_lcbClx < 0) | ||||||
1683 | return nullptr; | ||||||
1684 | |||||||
1685 | WW8_FC nClxPos = pWwF->m_fcClx; | ||||||
1686 | |||||||
1687 | if (!checkSeek(*pStr, nClxPos)) | ||||||
1688 | return nullptr; | ||||||
1689 | |||||||
1690 | sal_Int32 nClxLen = pWwF->m_lcbClx; | ||||||
1691 | sal_Int32 nLeft = nClxLen; | ||||||
1692 | |||||||
1693 | while (true) | ||||||
1694 | { | ||||||
1695 | sal_uInt8 clxt(2); | ||||||
1696 | pStr->ReadUChar( clxt ); | ||||||
1697 | nLeft--; | ||||||
1698 | if( 2 == clxt) // PLCFfpcd ? | ||||||
1699 | break; // PLCFfpcd found | ||||||
1700 | sal_uInt16 nLen(0); | ||||||
1701 | pStr->ReadUInt16( nLen ); | ||||||
1702 | nLeft -= 2 + nLen; | ||||||
1703 | if( nLeft < 0 ) | ||||||
1704 | return nullptr; // gone wrong | ||||||
1705 | if( 1 == clxt ) // clxtGrpprl ? | ||||||
1706 | { | ||||||
1707 | if (m_aPieceGrpprls.size() == SHRT_MAX32767) | ||||||
1708 | return nullptr; | ||||||
1709 | if (nLen > pStr->remainingSize()) | ||||||
1710 | return nullptr; | ||||||
1711 | std::unique_ptr<sal_uInt8[]> p(new sal_uInt8[nLen+2]); // allocate | ||||||
1712 | ShortToSVBT16(nLen, p.get()); // add length | ||||||
1713 | if (!checkRead(*pStr, p.get()+2, nLen)) // read grpprl | ||||||
1714 | { | ||||||
1715 | return nullptr; | ||||||
1716 | } | ||||||
1717 | m_aPieceGrpprls.push_back(std::move(p)); // add to array | ||||||
1718 | } | ||||||
1719 | else | ||||||
1720 | { | ||||||
1721 | nLen = std::min<sal_uInt64>(nLen, pStr->remainingSize()); | ||||||
1722 | pStr->Seek(pStr->Tell() + nLen); // non-Grpprl left | ||||||
1723 | } | ||||||
1724 | } | ||||||
1725 | |||||||
1726 | // read Piece Table PLCF | ||||||
1727 | sal_Int32 nPLCFfLen(0); | ||||||
1728 | if (pWwF->GetFIBVersion() <= ww::eWW2) | ||||||
1729 | { | ||||||
1730 | sal_Int16 nWordTwoLen(0); | ||||||
1731 | pStr->ReadInt16( nWordTwoLen ); | ||||||
1732 | nPLCFfLen = nWordTwoLen; | ||||||
1733 | } | ||||||
1734 | else | ||||||
1735 | pStr->ReadInt32( nPLCFfLen ); | ||||||
1736 | OSL_ENSURE( 65536 > nPLCFfLen, "PLCFfpcd above 64 k" )do { if (true && (!(65536 > nPLCFfLen))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1736" ": "), "%s", "PLCFfpcd above 64 k"); } } while (false ); | ||||||
1737 | return std::make_unique<WW8PLCFpcd>( pStr, pStr->Tell(), nPLCFfLen, 8 ); | ||||||
1738 | } | ||||||
1739 | |||||||
1740 | WW8ScannerBase::WW8ScannerBase( SvStream* pSt, SvStream* pTableSt, | ||||||
1741 | SvStream* pDataSt, WW8Fib* pWwFib ) | ||||||
1742 | : m_pWw8Fib(pWwFib) | ||||||
1743 | { | ||||||
1744 | m_pPiecePLCF = OpenPieceTable( pTableSt, m_pWw8Fib ); // Complex | ||||||
1745 | if( m_pPiecePLCF ) | ||||||
1746 | { | ||||||
1747 | m_pPieceIter.reset(new WW8PLCFpcd_Iter( *m_pPiecePLCF )); | ||||||
1748 | m_pPLCFx_PCD.reset( new WW8PLCFx_PCD(*pWwFib, m_pPiecePLCF.get(), 0, | ||||||
1749 | IsSevenMinus(m_pWw8Fib->GetFIBVersion()))); | ||||||
1750 | m_pPLCFx_PCDAttrs.reset(new WW8PLCFx_PCDAttrs(*pWwFib, | ||||||
1751 | m_pPLCFx_PCD.get(), this)); | ||||||
1752 | } | ||||||
1753 | else | ||||||
1754 | { | ||||||
1755 | m_pPieceIter = nullptr; | ||||||
1756 | m_pPLCFx_PCD = nullptr; | ||||||
1757 | m_pPLCFx_PCDAttrs = nullptr; | ||||||
1758 | } | ||||||
1759 | |||||||
1760 | // pChpPLCF and pPapPLCF may NOT be created before pPLCFx_PCD !! | ||||||
1761 | m_pChpPLCF.reset(new WW8PLCFx_Cp_FKP( pSt, pTableSt, pDataSt, *this, CHP )); // CHPX | ||||||
1762 | m_pPapPLCF.reset(new WW8PLCFx_Cp_FKP( pSt, pTableSt, pDataSt, *this, PAP )); // PAPX | ||||||
1763 | |||||||
1764 | m_pSepPLCF.reset(new WW8PLCFx_SEPX( pSt, pTableSt, *pWwFib, 0 )); // SEPX | ||||||
1765 | |||||||
1766 | // Footnotes | ||||||
1767 | m_pFootnotePLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0, | ||||||
1768 | pWwFib->m_fcPlcffndRef, pWwFib->m_lcbPlcffndRef, pWwFib->m_fcPlcffndText, | ||||||
1769 | pWwFib->m_lcbPlcffndText, 2 )); | ||||||
1770 | // Endnotes | ||||||
1771 | m_pEdnPLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0, | ||||||
1772 | pWwFib->m_fcPlcfendRef, pWwFib->m_lcbPlcfendRef, pWwFib->m_fcPlcfendText, | ||||||
1773 | pWwFib->m_lcbPlcfendText, 2 )); | ||||||
1774 | // Comments | ||||||
1775 | m_pAndPLCF.reset(new WW8PLCFx_SubDoc( pTableSt, *pWwFib, 0, | ||||||
1776 | pWwFib->m_fcPlcfandRef, pWwFib->m_lcbPlcfandRef, pWwFib->m_fcPlcfandText, | ||||||
1777 | pWwFib->m_lcbPlcfandText, IsSevenMinus(pWwFib->GetFIBVersion()) ? 20 : 30)); | ||||||
1778 | |||||||
1779 | // Fields Main Text | ||||||
1780 | m_pFieldPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_MAINTEXT)); | ||||||
1781 | // Fields Header / Footer | ||||||
1782 | m_pFieldHdFtPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_HDFT)); | ||||||
1783 | // Fields Footnote | ||||||
1784 | m_pFieldFootnotePLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_FTN)); | ||||||
1785 | // Fields Endnote | ||||||
1786 | m_pFieldEdnPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_EDN)); | ||||||
1787 | // Fields Comments | ||||||
1788 | m_pFieldAndPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_AND)); | ||||||
1789 | // Fields in Textboxes in Main Text | ||||||
1790 | m_pFieldTxbxPLCF.reset(new WW8PLCFx_FLD(pTableSt, *pWwFib, MAN_TXBX)); | ||||||
1791 | // Fields in Textboxes in Header / Footer | ||||||
1792 | m_pFieldTxbxHdFtPLCF.reset(new WW8PLCFx_FLD(pTableSt,*pWwFib,MAN_TXBX_HDFT)); | ||||||
1793 | |||||||
1794 | // Note: 6 stands for "6 OR 7", 7 stands for "ONLY 7" | ||||||
1795 | switch( m_pWw8Fib->m_nVersion ) | ||||||
1796 | { | ||||||
1797 | case 6: | ||||||
1798 | case 7: | ||||||
1799 | if( pWwFib->m_fcPlcfdoaMom && pWwFib->m_lcbPlcfdoaMom ) | ||||||
1800 | { | ||||||
1801 | m_pMainFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfdoaMom, | ||||||
1802 | pWwFib->m_lcbPlcfdoaMom, 6 )); | ||||||
1803 | } | ||||||
1804 | if( pWwFib->m_fcPlcfdoaHdr && pWwFib->m_lcbPlcfdoaHdr ) | ||||||
1805 | { | ||||||
1806 | m_pHdFtFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfdoaHdr, | ||||||
1807 | pWwFib->m_lcbPlcfdoaHdr, 6 )); | ||||||
1808 | } | ||||||
1809 | break; | ||||||
1810 | case 8: | ||||||
1811 | if( pWwFib->m_fcPlcfspaMom && pWwFib->m_lcbPlcfspaMom ) | ||||||
1812 | { | ||||||
1813 | m_pMainFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfspaMom, | ||||||
1814 | pWwFib->m_lcbPlcfspaMom, 26 )); | ||||||
1815 | } | ||||||
1816 | if( pWwFib->m_fcPlcfspaHdr && pWwFib->m_lcbPlcfspaHdr ) | ||||||
1817 | { | ||||||
1818 | m_pHdFtFdoa.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfspaHdr, | ||||||
1819 | pWwFib->m_lcbPlcfspaHdr, 26 )); | ||||||
1820 | } | ||||||
1821 | // PLCF for TextBox break-descriptors in the main text | ||||||
1822 | if( pWwFib->m_fcPlcftxbxBkd && pWwFib->m_lcbPlcftxbxBkd ) | ||||||
1823 | { | ||||||
1824 | m_pMainTxbxBkd.reset(new WW8PLCFspecial( pTableSt, | ||||||
1825 | pWwFib->m_fcPlcftxbxBkd, pWwFib->m_lcbPlcftxbxBkd, 0)); | ||||||
1826 | } | ||||||
1827 | // PLCF for TextBox break-descriptors in Header/Footer range | ||||||
1828 | if( pWwFib->m_fcPlcfHdrtxbxBkd && pWwFib->m_lcbPlcfHdrtxbxBkd ) | ||||||
1829 | { | ||||||
1830 | m_pHdFtTxbxBkd.reset(new WW8PLCFspecial( pTableSt, | ||||||
1831 | pWwFib->m_fcPlcfHdrtxbxBkd, pWwFib->m_lcbPlcfHdrtxbxBkd, 0)); | ||||||
1832 | } | ||||||
1833 | // Sub table cp positions | ||||||
1834 | if (pWwFib->m_fcPlcfTch && pWwFib->m_lcbPlcfTch) | ||||||
1835 | { | ||||||
1836 | m_pMagicTables.reset(new WW8PLCFspecial( pTableSt, | ||||||
1837 | pWwFib->m_fcPlcfTch, pWwFib->m_lcbPlcfTch, 4)); | ||||||
1838 | } | ||||||
1839 | // Sub document cp positions | ||||||
1840 | if (pWwFib->m_fcPlcfwkb && pWwFib->m_lcbPlcfwkb) | ||||||
1841 | { | ||||||
1842 | m_pSubdocs.reset(new WW8PLCFspecial( pTableSt, | ||||||
1843 | pWwFib->m_fcPlcfwkb, pWwFib->m_lcbPlcfwkb, 12)); | ||||||
1844 | } | ||||||
1845 | // Extended ATRD | ||||||
1846 | if (pWwFib->m_fcAtrdExtra && pWwFib->m_lcbAtrdExtra) | ||||||
1847 | { | ||||||
1848 | sal_uInt64 const nOldPos = pTableSt->Tell(); | ||||||
1849 | if (checkSeek(*pTableSt, pWwFib->m_fcAtrdExtra) && (pTableSt->remainingSize() >= pWwFib->m_lcbAtrdExtra)) | ||||||
1850 | { | ||||||
1851 | m_pExtendedAtrds.reset( new sal_uInt8[pWwFib->m_lcbAtrdExtra] ); | ||||||
1852 | pWwFib->m_lcbAtrdExtra = pTableSt->ReadBytes(m_pExtendedAtrds.get(), pWwFib->m_lcbAtrdExtra); | ||||||
1853 | } | ||||||
1854 | else | ||||||
1855 | pWwFib->m_lcbAtrdExtra = 0; | ||||||
1856 | pTableSt->Seek(nOldPos); | ||||||
1857 | } | ||||||
1858 | |||||||
1859 | break; | ||||||
1860 | default: | ||||||
1861 | OSL_ENSURE( false, "nVersion not implemented!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "1861" ": "), "%s", "nVersion not implemented!"); } } while (false); | ||||||
1862 | break; | ||||||
1863 | } | ||||||
1864 | |||||||
1865 | // PLCF for TextBox stories in main text | ||||||
1866 | sal_uInt32 nLenTxBxS = (8 > m_pWw8Fib->m_nVersion) ? 0 : 22; | ||||||
1867 | if( pWwFib->m_fcPlcftxbxText && pWwFib->m_lcbPlcftxbxText ) | ||||||
1868 | { | ||||||
1869 | m_pMainTxbx.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcftxbxText, | ||||||
1870 | pWwFib->m_lcbPlcftxbxText, nLenTxBxS )); | ||||||
1871 | } | ||||||
1872 | |||||||
1873 | // PLCF for TextBox stories in Header/Footer range | ||||||
1874 | if( pWwFib->m_fcPlcfHdrtxbxText && pWwFib->m_lcbPlcfHdrtxbxText ) | ||||||
1875 | { | ||||||
1876 | m_pHdFtTxbx.reset(new WW8PLCFspecial( pTableSt, pWwFib->m_fcPlcfHdrtxbxText, | ||||||
1877 | pWwFib->m_lcbPlcfHdrtxbxText, nLenTxBxS )); | ||||||
1878 | } | ||||||
1879 | |||||||
1880 | m_pBook.reset(new WW8PLCFx_Book(pTableSt, *pWwFib)); | ||||||
1881 | m_pAtnBook.reset(new WW8PLCFx_AtnBook(pTableSt, *pWwFib)); | ||||||
1882 | m_pFactoidBook.reset(new WW8PLCFx_FactoidBook(pTableSt, *pWwFib)); | ||||||
1883 | } | ||||||
1884 | |||||||
1885 | WW8ScannerBase::~WW8ScannerBase() | ||||||
1886 | { | ||||||
1887 | m_aPieceGrpprls.clear(); | ||||||
1888 | m_pPLCFx_PCDAttrs.reset(); | ||||||
1889 | m_pPLCFx_PCD.reset(); | ||||||
1890 | m_pPieceIter.reset(); | ||||||
1891 | m_pPiecePLCF.reset(); | ||||||
1892 | m_pFactoidBook.reset(); | ||||||
1893 | m_pAtnBook.reset(); | ||||||
1894 | m_pBook.reset(); | ||||||
1895 | m_pFieldEdnPLCF.reset(); | ||||||
1896 | m_pFieldFootnotePLCF.reset(); | ||||||
1897 | m_pFieldAndPLCF.reset(); | ||||||
1898 | m_pFieldHdFtPLCF.reset(); | ||||||
1899 | m_pFieldPLCF.reset(); | ||||||
1900 | m_pFieldTxbxPLCF.reset(); | ||||||
1901 | m_pFieldTxbxHdFtPLCF.reset(); | ||||||
1902 | m_pEdnPLCF.reset(); | ||||||
1903 | m_pFootnotePLCF.reset(); | ||||||
1904 | m_pAndPLCF.reset(); | ||||||
1905 | m_pSepPLCF.reset(); | ||||||
1906 | m_pPapPLCF.reset(); | ||||||
1907 | m_pChpPLCF.reset(); | ||||||
1908 | m_pMainFdoa.reset(); | ||||||
1909 | m_pHdFtFdoa.reset(); | ||||||
1910 | m_pMainTxbx.reset(); | ||||||
1911 | m_pMainTxbxBkd.reset(); | ||||||
1912 | m_pHdFtTxbx.reset(); | ||||||
1913 | m_pHdFtTxbxBkd.reset(); | ||||||
1914 | m_pMagicTables.reset(); | ||||||
1915 | m_pSubdocs.reset(); | ||||||
1916 | } | ||||||
1917 | |||||||
1918 | // Fields | ||||||
1919 | |||||||
1920 | static bool WW8SkipField(WW8PLCFspecial& rPLCF) | ||||||
1921 | { | ||||||
1922 | void* pData; | ||||||
1923 | WW8_CP nP; | ||||||
1924 | |||||||
1925 | if (!rPLCF.Get(nP, pData)) // End of PLCFspecial? | ||||||
1926 | return false; | ||||||
1927 | |||||||
1928 | rPLCF.advance(); | ||||||
1929 | |||||||
1930 | if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) != 0x13 ) // No beginning? | ||||||
1931 | return true; // Do not terminate on error | ||||||
1932 | |||||||
1933 | if( !rPLCF.Get( nP, pData ) ) | ||||||
1934 | return false; | ||||||
1935 | |||||||
1936 | while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 ) | ||||||
1937 | { | ||||||
1938 | // still new (nested) beginnings ? | ||||||
1939 | WW8SkipField( rPLCF ); // nested Field in description | ||||||
1940 | if( !rPLCF.Get( nP, pData ) ) | ||||||
1941 | return false; | ||||||
1942 | } | ||||||
1943 | |||||||
1944 | if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x14 ) | ||||||
1945 | { | ||||||
1946 | |||||||
1947 | // Field Separator ? | ||||||
1948 | rPLCF.advance(); | ||||||
1949 | |||||||
1950 | if( !rPLCF.Get( nP, pData ) ) | ||||||
1951 | return false; | ||||||
1952 | |||||||
1953 | while ((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13) | ||||||
1954 | { | ||||||
1955 | // still new (nested) beginnings? | ||||||
1956 | WW8SkipField( rPLCF ); // nested Field in Results | ||||||
1957 | if( !rPLCF.Get( nP, pData ) ) | ||||||
1958 | return false; | ||||||
1959 | } | ||||||
1960 | } | ||||||
1961 | rPLCF.advance(); | ||||||
1962 | |||||||
1963 | return true; | ||||||
1964 | } | ||||||
1965 | |||||||
1966 | static bool WW8GetFieldPara(WW8PLCFspecial& rPLCF, WW8FieldDesc& rF) | ||||||
1967 | { | ||||||
1968 | void* pData; | ||||||
1969 | sal_uInt32 nOldIdx = rPLCF.GetIdx(); | ||||||
1970 | |||||||
1971 | rF.nLen = rF.nId = rF.nOpt = 0; | ||||||
1972 | rF.bCodeNest = rF.bResNest = false; | ||||||
1973 | |||||||
1974 | if (!rPLCF.Get(rF.nSCode, pData) || rF.nSCode < 0) // end of PLCFspecial? | ||||||
1975 | goto Err; | ||||||
1976 | |||||||
1977 | rPLCF.advance(); | ||||||
1978 | |||||||
1979 | if (!pData
| ||||||
1980 | goto Err; | ||||||
1981 | |||||||
1982 | rF.nId = static_cast<sal_uInt8*>(pData)[1]; | ||||||
1983 | |||||||
1984 | if( !rPLCF.Get( rF.nLCode, pData ) ) | ||||||
1985 | goto Err; | ||||||
1986 | |||||||
1987 | if (rF.nLCode < rF.nSCode) | ||||||
1988 | goto Err; | ||||||
1989 | |||||||
1990 | rF.nSRes = rF.nLCode; // Default | ||||||
1991 | rF.nSCode++; // without markers | ||||||
1992 | rF.nLCode -= rF.nSCode; // Pos -> length | ||||||
1993 | |||||||
1994 | while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 ) | ||||||
| |||||||
1995 | { | ||||||
1996 | // still new (nested) beginnings ? | ||||||
1997 | WW8SkipField( rPLCF ); // nested Field in description | ||||||
1998 | rF.bCodeNest = true; | ||||||
1999 | if (!rPLCF.Get(rF.nSRes, pData) || rF.nSRes < 0) | ||||||
2000 | goto Err; | ||||||
2001 | } | ||||||
2002 | |||||||
2003 | if ((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x14 ) // Field Separator? | ||||||
2004 | { | ||||||
2005 | rPLCF.advance(); | ||||||
2006 | |||||||
2007 | if (!rPLCF.Get(rF.nLRes, pData) || rF.nLRes < 0) | ||||||
2008 | goto Err; | ||||||
2009 | |||||||
2010 | while((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x13 ) | ||||||
2011 | { | ||||||
2012 | // still new (nested) beginnings ? | ||||||
2013 | WW8SkipField( rPLCF ); // nested Field in results | ||||||
2014 | rF.bResNest = true; | ||||||
2015 | if (!rPLCF.Get(rF.nLRes, pData) || rF.nLRes < 0) | ||||||
2016 | goto Err; | ||||||
2017 | } | ||||||
2018 | WW8_CP nTmp; | ||||||
2019 | if (o3tl::checked_sub<WW8_CP>(rF.nLRes, rF.nSCode, nTmp)) | ||||||
2020 | { | ||||||
2021 | rF.nLen = 0; | ||||||
2022 | goto Err; | ||||||
2023 | } | ||||||
2024 | if (o3tl::checked_add<WW8_CP>(nTmp, 2, rF.nLen)) // nLRes is still the final position | ||||||
2025 | { | ||||||
2026 | rF.nLen = 0; | ||||||
2027 | goto Err; | ||||||
2028 | } | ||||||
2029 | rF.nLRes -= rF.nSRes; // now: nLRes = length | ||||||
2030 | if (o3tl::checked_add<WW8_CP>(rF.nSRes, 1, rF.nSRes)) // Endpos including Markers | ||||||
2031 | { | ||||||
2032 | rF.nLen = 0; | ||||||
2033 | goto Err; | ||||||
2034 | } | ||||||
2035 | rF.nLRes--; | ||||||
2036 | }else{ | ||||||
2037 | rF.nLRes = 0; // no result found | ||||||
2038 | WW8_CP nTmp; | ||||||
2039 | if (o3tl::checked_sub<WW8_CP>(rF.nSRes, rF.nSCode, nTmp)) | ||||||
2040 | { | ||||||
2041 | rF.nLen = 0; | ||||||
2042 | goto Err; | ||||||
2043 | } | ||||||
2044 | if (o3tl::checked_add<WW8_CP>(nTmp, 2, rF.nLen)) // total length | ||||||
2045 | { | ||||||
2046 | rF.nLen = 0; | ||||||
2047 | goto Err; | ||||||
2048 | } | ||||||
2049 | } | ||||||
2050 | |||||||
2051 | if (rF.nLen < 0) | ||||||
2052 | { | ||||||
2053 | rF.nLen = 0; | ||||||
2054 | goto Err; | ||||||
2055 | } | ||||||
2056 | |||||||
2057 | rPLCF.advance(); | ||||||
2058 | if((static_cast<sal_uInt8*>(pData)[0] & 0x1f ) == 0x15 ) | ||||||
2059 | { | ||||||
2060 | // Field end ? | ||||||
2061 | // INDEX-Field has set Bit7? | ||||||
2062 | rF.nOpt = static_cast<sal_uInt8*>(pData)[1]; // yes -> copy flags | ||||||
2063 | }else{ | ||||||
2064 | rF.nId = 0; // no -> Field invalid | ||||||
2065 | } | ||||||
2066 | |||||||
2067 | rPLCF.SetIdx( nOldIdx ); | ||||||
2068 | return true; | ||||||
2069 | Err: | ||||||
2070 | rPLCF.SetIdx( nOldIdx ); | ||||||
2071 | return false; | ||||||
2072 | } | ||||||
2073 | |||||||
2074 | OUString read_uInt8_BeltAndBracesString(SvStream& rStrm, rtl_TextEncoding eEnc) | ||||||
2075 | { | ||||||
2076 | const OUString aRet = read_uInt8_lenPrefixed_uInt8s_ToOUString(rStrm, eEnc); | ||||||
2077 | rStrm.SeekRel(sizeof(sal_uInt8)); // skip null-byte at end | ||||||
2078 | return aRet; | ||||||
2079 | } | ||||||
2080 | |||||||
2081 | OUString read_uInt16_BeltAndBracesString(SvStream& rStrm) | ||||||
2082 | { | ||||||
2083 | const OUString aRet = read_uInt16_PascalString(rStrm); | ||||||
2084 | rStrm.SeekRel(sizeof(sal_Unicode)); // skip null-byte at end | ||||||
2085 | return aRet; | ||||||
2086 | } | ||||||
2087 | |||||||
2088 | sal_Int32 WW8ScannerBase::WW8ReadString( SvStream& rStrm, OUString& rStr, | ||||||
2089 | WW8_CP nCurrentStartCp, long nTotalLen, rtl_TextEncoding eEnc ) const | ||||||
2090 | { | ||||||
2091 | // Read in plain text, which can extend over several pieces | ||||||
2092 | rStr.clear(); | ||||||
2093 | |||||||
2094 | if (nCurrentStartCp < 0 || nTotalLen < 0) | ||||||
2095 | return 0; | ||||||
2096 | |||||||
2097 | WW8_CP nBehindTextCp = nCurrentStartCp + nTotalLen; | ||||||
2098 | WW8_CP nNextPieceCp = nBehindTextCp; // Initialization, important for Ver6 | ||||||
2099 | long nTotalRead = 0; | ||||||
2100 | do | ||||||
2101 | { | ||||||
2102 | bool bIsUnicode(false), bPosOk(false); | ||||||
2103 | WW8_FC fcAct = WW8Cp2Fc(nCurrentStartCp,&bIsUnicode,&nNextPieceCp,&bPosOk); | ||||||
2104 | |||||||
2105 | // Probably aimed beyond file end, doesn't matter! | ||||||
2106 | if( !bPosOk ) | ||||||
2107 | break; | ||||||
2108 | |||||||
2109 | bool bValid = checkSeek(rStrm, fcAct); | ||||||
2110 | if (!bValid) | ||||||
2111 | break; | ||||||
2112 | |||||||
2113 | WW8_CP nEnd = (nNextPieceCp < nBehindTextCp) ? nNextPieceCp | ||||||
2114 | : nBehindTextCp; | ||||||
2115 | WW8_CP nLen; | ||||||
2116 | const bool bFail = o3tl::checked_sub(nEnd, nCurrentStartCp, nLen); | ||||||
2117 | if (bFail) | ||||||
2118 | break; | ||||||
2119 | |||||||
2120 | if( 0 >= nLen ) | ||||||
2121 | break; | ||||||
2122 | |||||||
2123 | rStr += bIsUnicode | ||||||
2124 | ? read_uInt16s_ToOUString(rStrm, nLen) | ||||||
2125 | : read_uInt8s_ToOUString(rStrm, nLen, eEnc); | ||||||
2126 | |||||||
2127 | nTotalRead += nLen; | ||||||
2128 | nCurrentStartCp += nLen; | ||||||
2129 | if ( nTotalRead != rStr.getLength() ) | ||||||
2130 | break; | ||||||
2131 | } | ||||||
2132 | while( nTotalRead < nTotalLen ); | ||||||
2133 | |||||||
2134 | return rStr.getLength(); | ||||||
2135 | } | ||||||
2136 | |||||||
2137 | WW8PLCFspecial::WW8PLCFspecial(SvStream* pSt, sal_uInt32 nFilePos, | ||||||
2138 | sal_uInt32 nPLCF, sal_uInt32 nStruct) | ||||||
2139 | : nIdx(0), nStru(nStruct) | ||||||
2140 | { | ||||||
2141 | const sal_uInt32 nValidMin=4; | ||||||
2142 | |||||||
2143 | sal_uInt64 const nOldPos = pSt->Tell(); | ||||||
2144 | |||||||
2145 | bool bValid = checkSeek(*pSt, nFilePos); | ||||||
2146 | std::size_t nRemainingSize = pSt->remainingSize(); | ||||||
2147 | if( nRemainingSize < nValidMin || nPLCF < nValidMin ) | ||||||
2148 | bValid = false; | ||||||
2149 | nPLCF = bValid ? std::min(nRemainingSize, static_cast<std::size_t>(nPLCF)) : nValidMin; | ||||||
2150 | |||||||
2151 | // Pointer to Pos- and Struct-array | ||||||
2152 | pPLCF_PosArray.reset( new sal_Int32[ ( nPLCF + 3 ) / 4 ] ); | ||||||
2153 | pPLCF_PosArray[0] = 0; | ||||||
2154 | |||||||
2155 | nPLCF = bValid ? pSt->ReadBytes(pPLCF_PosArray.get(), nPLCF) : nValidMin; | ||||||
2156 | |||||||
2157 | nPLCF = std::max(nPLCF, nValidMin); | ||||||
2158 | |||||||
2159 | nIMax = ( nPLCF - 4 ) / ( 4 + nStruct ); | ||||||
2160 | #ifdef OSL_BIGENDIAN | ||||||
2161 | for( nIdx = 0; nIdx <= nIMax; nIdx++ ) | ||||||
2162 | pPLCF_PosArray[nIdx] = OSL_SWAPDWORD( pPLCF_PosArray[nIdx] )((sal_uInt32)((((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16 )(((sal_uInt16)(((sal_uInt32)(pPLCF_PosArray[nIdx]) >> 16 ) & 0xFFFF))) >> 8) & 0xFF))) & 0xFF) | ((( sal_uInt16)(((sal_uInt8)((sal_uInt16)(((sal_uInt16)(((sal_uInt32 )(pPLCF_PosArray[nIdx]) >> 16) & 0xFFFF))) & 0xFF ))) & 0xFF) << 8)))) & 0xFFFF) | (((sal_uInt32) (((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16)(((sal_uInt16 )((sal_uInt32)(pPLCF_PosArray[nIdx]) & 0xFFFF))) >> 8) & 0xFF))) & 0xFF) | (((sal_uInt16)(((sal_uInt8)(( sal_uInt16)(((sal_uInt16)((sal_uInt32)(pPLCF_PosArray[nIdx]) & 0xFFFF))) & 0xFF))) & 0xFF) << 8)))) & 0xFFFF ) << 16)); | ||||||
2163 | nIdx = 0; | ||||||
2164 | #endif // OSL_BIGENDIAN | ||||||
2165 | if( nStruct ) // Pointer to content array | ||||||
2166 | pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]); | ||||||
2167 | else | ||||||
2168 | pPLCF_Contents = nullptr; // no content | ||||||
2169 | |||||||
2170 | pSt->Seek(nOldPos); | ||||||
2171 | } | ||||||
2172 | |||||||
2173 | // WW8PLCFspecial::SeekPos() sets WW8PLCFspecial to position nPos, while also the entry is used | ||||||
2174 | // that begins before nPos and ends after nPos. | ||||||
2175 | // Suitable for normal attributes. However, the beginning of the attribute is not corrected onto | ||||||
2176 | // the position nPos. | ||||||
2177 | bool WW8PLCFspecial::SeekPos(long nP) | ||||||
2178 | { | ||||||
2179 | if( nP < pPLCF_PosArray[0] ) | ||||||
2180 | { | ||||||
2181 | nIdx = 0; | ||||||
2182 | return false; // Not found: nP less than smallest entry | ||||||
2183 | } | ||||||
2184 | |||||||
2185 | // Search from beginning? | ||||||
2186 | if ((nIdx < 1) || (nP < pPLCF_PosArray[nIdx - 1])) | ||||||
2187 | nIdx = 1; | ||||||
2188 | |||||||
2189 | long nI = nIdx; | ||||||
2190 | long nEnd = nIMax; | ||||||
2191 | |||||||
2192 | for(int n = (1==nIdx ? 1 : 2); n; --n ) | ||||||
2193 | { | ||||||
2194 | for( ; nI <=nEnd; ++nI) | ||||||
2195 | { // search with an index that is incremented by 1 | ||||||
2196 | if( nP < pPLCF_PosArray[nI] ) | ||||||
2197 | { // found position | ||||||
2198 | nIdx = nI - 1; // nI - 1 is the correct index | ||||||
2199 | return true; // done | ||||||
2200 | } | ||||||
2201 | } | ||||||
2202 | nI = 1; | ||||||
2203 | nEnd = nIdx-1; | ||||||
2204 | } | ||||||
2205 | nIdx = nIMax; // not found, greater than all entries | ||||||
2206 | return false; | ||||||
2207 | } | ||||||
2208 | |||||||
2209 | // WW8PLCFspecial::SeekPosExact() like SeekPos(), but it is ensured that no attribute is cut, | ||||||
2210 | // i.e. the next given attribute begins at or after nPos. | ||||||
2211 | // Is used for fields and bookmarks. | ||||||
2212 | bool WW8PLCFspecial::SeekPosExact(long nP) | ||||||
2213 | { | ||||||
2214 | if( nP < pPLCF_PosArray[0] ) | ||||||
2215 | { | ||||||
2216 | nIdx = 0; | ||||||
2217 | return false; // Not found: nP less than smallest entry | ||||||
2218 | } | ||||||
2219 | // Search from beginning? | ||||||
2220 | if( nP <=pPLCF_PosArray[nIdx] ) | ||||||
2221 | nIdx = 0; | ||||||
2222 | |||||||
2223 | long nI = nIdx ? nIdx-1 : 0; | ||||||
2224 | long nEnd = nIMax; | ||||||
2225 | |||||||
2226 | for(int n = (0==nIdx ? 1 : 2); n; --n ) | ||||||
2227 | { | ||||||
2228 | for( ; nI < nEnd; ++nI) | ||||||
2229 | { | ||||||
2230 | if( nP <=pPLCF_PosArray[nI] ) | ||||||
2231 | { // found position | ||||||
2232 | nIdx = nI; // nI is the correct index | ||||||
2233 | return true; // done | ||||||
2234 | } | ||||||
2235 | } | ||||||
2236 | nI = 0; | ||||||
2237 | nEnd = nIdx; | ||||||
2238 | } | ||||||
2239 | nIdx = nIMax; // Not found, greater than all entries | ||||||
2240 | return false; | ||||||
2241 | } | ||||||
2242 | |||||||
2243 | bool WW8PLCFspecial::Get(WW8_CP& rPos, void*& rpValue) const | ||||||
2244 | { | ||||||
2245 | return GetData( nIdx, rPos, rpValue ); | ||||||
2246 | } | ||||||
2247 | |||||||
2248 | bool WW8PLCFspecial::GetData(long nInIdx, WW8_CP& rPos, void*& rpValue) const | ||||||
2249 | { | ||||||
2250 | if ( nInIdx >= nIMax ) | ||||||
2251 | { | ||||||
2252 | rPos = WW8_CP_MAX; | ||||||
2253 | return false; | ||||||
2254 | } | ||||||
2255 | rPos = pPLCF_PosArray[nInIdx]; | ||||||
2256 | rpValue = pPLCF_Contents
| ||||||
2257 | return true; | ||||||
2258 | } | ||||||
2259 | |||||||
2260 | // WW8PLCF e.g. for SEPX | ||||||
2261 | // Ctor for *others* than Fkps | ||||||
2262 | // With nStartPos < 0, the first element of PLCFs will be taken | ||||||
2263 | WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, | ||||||
2264 | WW8_CP nStartPos) : nIdx(0), nStru(nStruct) | ||||||
2265 | { | ||||||
2266 | if (nPLCF < 0) | ||||||
2267 | { | ||||||
2268 | SAL_WARN("sw.ww8", "broken WW8PLCF, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken WW8PLCF, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2268" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken WW8PLCF, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken WW8PLCF, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2268" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken WW8PLCF, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2268" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken WW8PLCF, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken WW8PLCF, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2268" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2269 | nPLCF = 0; | ||||||
2270 | } | ||||||
2271 | else | ||||||
2272 | nIMax = (nPLCF - 4) / (4 + nStruct); | ||||||
2273 | |||||||
2274 | ReadPLCF(rSt, nFilePos, nPLCF); | ||||||
2275 | |||||||
2276 | if( nStartPos >= 0 ) | ||||||
2277 | SeekPos( nStartPos ); | ||||||
2278 | } | ||||||
2279 | |||||||
2280 | // Ctor *only* for Fkps | ||||||
2281 | // The last 2 parameters are needed for PLCF.Chpx and PLCF.Papx. | ||||||
2282 | // If ncpN != 0, then an incomplete PLCF will be completed. This is always required for WW6 with | ||||||
2283 | // lack of resources and for WordPad (W95). | ||||||
2284 | // With nStartPos < 0, the first element of the PLCFs is taken. | ||||||
2285 | WW8PLCF::WW8PLCF(SvStream& rSt, WW8_FC nFilePos, sal_Int32 nPLCF, int nStruct, | ||||||
2286 | WW8_CP nStartPos, sal_Int32 nPN, sal_Int32 ncpN): nIdx(0), | ||||||
2287 | nStru(nStruct) | ||||||
2288 | { | ||||||
2289 | if (nPLCF < 0) | ||||||
2290 | { | ||||||
2291 | SAL_WARN("sw.ww8", "broken WW8PLCF, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken WW8PLCF, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2291" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken WW8PLCF, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken WW8PLCF, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2291" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken WW8PLCF, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2291" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken WW8PLCF, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken WW8PLCF, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2291" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2292 | nIMax = SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF); | ||||||
2293 | } | ||||||
2294 | else | ||||||
2295 | nIMax = (nPLCF - 4) / (4 + nStruct); | ||||||
2296 | |||||||
2297 | if( nIMax >= ncpN ) | ||||||
2298 | ReadPLCF(rSt, nFilePos, nPLCF); | ||||||
2299 | else | ||||||
2300 | GeneratePLCF(rSt, nPN, ncpN); | ||||||
2301 | |||||||
2302 | if( nStartPos >= 0 ) | ||||||
2303 | SeekPos( nStartPos ); | ||||||
2304 | } | ||||||
2305 | |||||||
2306 | void WW8PLCF::ReadPLCF(SvStream& rSt, WW8_FC nFilePos, sal_uInt32 nPLCF) | ||||||
2307 | { | ||||||
2308 | sal_uInt64 const nOldPos = rSt.Tell(); | ||||||
2309 | bool bValid = nPLCF != 0 && checkSeek(rSt, nFilePos) | ||||||
2310 | && (rSt.remainingSize() >= nPLCF); | ||||||
2311 | |||||||
2312 | if (bValid) | ||||||
2313 | { | ||||||
2314 | // Pointer to Pos-array | ||||||
2315 | pPLCF_PosArray.reset( new WW8_CP[ ( nPLCF + 3 ) / 4 ] ); | ||||||
2316 | bValid = checkRead(rSt, pPLCF_PosArray.get(), nPLCF); | ||||||
2317 | } | ||||||
2318 | |||||||
2319 | if (bValid) | ||||||
2320 | { | ||||||
2321 | #ifdef OSL_BIGENDIAN | ||||||
2322 | for( nIdx = 0; nIdx <= nIMax; nIdx++ ) | ||||||
2323 | pPLCF_PosArray[nIdx] = OSL_SWAPDWORD( pPLCF_PosArray[nIdx] )((sal_uInt32)((((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16 )(((sal_uInt16)(((sal_uInt32)(pPLCF_PosArray[nIdx]) >> 16 ) & 0xFFFF))) >> 8) & 0xFF))) & 0xFF) | ((( sal_uInt16)(((sal_uInt8)((sal_uInt16)(((sal_uInt16)(((sal_uInt32 )(pPLCF_PosArray[nIdx]) >> 16) & 0xFFFF))) & 0xFF ))) & 0xFF) << 8)))) & 0xFFFF) | (((sal_uInt32) (((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16)(((sal_uInt16 )((sal_uInt32)(pPLCF_PosArray[nIdx]) & 0xFFFF))) >> 8) & 0xFF))) & 0xFF) | (((sal_uInt16)(((sal_uInt8)(( sal_uInt16)(((sal_uInt16)((sal_uInt32)(pPLCF_PosArray[nIdx]) & 0xFFFF))) & 0xFF))) & 0xFF) << 8)))) & 0xFFFF ) << 16)); | ||||||
2324 | nIdx = 0; | ||||||
2325 | #endif // OSL_BIGENDIAN | ||||||
2326 | // Pointer to content array | ||||||
2327 | pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]); | ||||||
2328 | |||||||
2329 | TruncToSortedRange(); | ||||||
2330 | } | ||||||
2331 | |||||||
2332 | OSL_ENSURE(bValid, "Document has corrupt PLCF, ignoring it")do { if (true && (!(bValid))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2332" ": "), "%s", "Document has corrupt PLCF, ignoring it" ); } } while (false); | ||||||
2333 | |||||||
2334 | if (!bValid) | ||||||
2335 | MakeFailedPLCF(); | ||||||
2336 | |||||||
2337 | rSt.Seek(nOldPos); | ||||||
2338 | } | ||||||
2339 | |||||||
2340 | void WW8PLCF::MakeFailedPLCF() | ||||||
2341 | { | ||||||
2342 | nIMax = 0; | ||||||
2343 | pPLCF_PosArray.reset( new sal_Int32[2] ); | ||||||
2344 | pPLCF_PosArray[0] = pPLCF_PosArray[1] = WW8_CP_MAX; | ||||||
2345 | pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]); | ||||||
2346 | } | ||||||
2347 | |||||||
2348 | void WW8PLCF::TruncToSortedRange() | ||||||
2349 | { | ||||||
2350 | //Docs state that: ... all Plcs ... are sorted in ascending order. | ||||||
2351 | //So ensure that here for broken documents. | ||||||
2352 | for (auto nI = 0; nI < nIMax; ++nI) | ||||||
2353 | { | ||||||
2354 | if (pPLCF_PosArray[nI] > pPLCF_PosArray[nI+1]) | ||||||
2355 | { | ||||||
2356 | SAL_WARN("sw.ww8", "Document has unsorted PLCF, truncated to sorted portion")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Document has unsorted PLCF, truncated to sorted portion" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2356" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has unsorted PLCF, truncated to sorted portion" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has unsorted PLCF, truncated to sorted portion" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2356" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Document has unsorted PLCF, truncated to sorted portion" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2356" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has unsorted PLCF, truncated to sorted portion" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has unsorted PLCF, truncated to sorted portion" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2356" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2357 | nIMax = nI; | ||||||
2358 | break; | ||||||
2359 | } | ||||||
2360 | } | ||||||
2361 | } | ||||||
2362 | |||||||
2363 | void WW8PLCF::GeneratePLCF(SvStream& rSt, sal_Int32 nPN, sal_Int32 ncpN) | ||||||
2364 | { | ||||||
2365 | OSL_ENSURE( nIMax < ncpN, "Pcl.Fkp: Why is PLCF too big?" )do { if (true && (!(nIMax < ncpN))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2365" ": "), "%s", "Pcl.Fkp: Why is PLCF too big?"); } } while (false); | ||||||
2366 | |||||||
2367 | bool failure = false; | ||||||
2368 | nIMax = ncpN; | ||||||
2369 | |||||||
2370 | if ((nIMax < 1) || (nIMax > (WW8_CP_MAX - 4) / (4 + nStru)) || nPN < 0) | ||||||
2371 | failure = true; | ||||||
2372 | |||||||
2373 | if (!failure) | ||||||
2374 | { | ||||||
2375 | // Check arguments to ShortToSVBT16 in loop below will all be valid: | ||||||
2376 | sal_Int32 nResult; | ||||||
2377 | failure = o3tl::checked_add(nPN, ncpN, nResult) || nResult > SAL_MAX_UINT16((sal_uInt16) 0xFFFF); | ||||||
2378 | } | ||||||
2379 | |||||||
2380 | if (!failure) | ||||||
2381 | { | ||||||
2382 | size_t nSiz = (4 + nStru) * nIMax + 4; | ||||||
2383 | size_t nElems = ( nSiz + 3 ) / 4; | ||||||
2384 | pPLCF_PosArray.reset( new sal_Int32[ nElems ] ); // Pointer to Pos-array | ||||||
2385 | |||||||
2386 | for (sal_Int32 i = 0; i < ncpN && !failure; ++i) | ||||||
2387 | { | ||||||
2388 | failure = true; | ||||||
2389 | // construct FC entries | ||||||
2390 | // first FC entry of each Fkp | ||||||
2391 | if (!checkSeek(rSt, (nPN + i) << 9)) | ||||||
2392 | break; | ||||||
2393 | |||||||
2394 | WW8_CP nFc(0); | ||||||
2395 | rSt.ReadInt32( nFc ); | ||||||
2396 | pPLCF_PosArray[i] = nFc; | ||||||
2397 | |||||||
2398 | failure = bool(rSt.GetError()); | ||||||
2399 | } | ||||||
2400 | } | ||||||
2401 | |||||||
2402 | if (!failure) | ||||||
2403 | { | ||||||
2404 | do | ||||||
2405 | { | ||||||
2406 | failure = true; | ||||||
2407 | |||||||
2408 | std::size_t nLastFkpPos = nPN + nIMax - 1; | ||||||
2409 | nLastFkpPos = nLastFkpPos << 9; | ||||||
2410 | // number of FC entries of last Fkp | ||||||
2411 | if (!checkSeek(rSt, nLastFkpPos + 511)) | ||||||
2412 | break; | ||||||
2413 | |||||||
2414 | sal_uInt8 nb(0); | ||||||
2415 | rSt.ReadUChar( nb ); | ||||||
2416 | // last FC entry of last Fkp | ||||||
2417 | if (!checkSeek(rSt, nLastFkpPos + nb * 4)) | ||||||
2418 | break; | ||||||
2419 | |||||||
2420 | WW8_CP nFc(0); | ||||||
2421 | rSt.ReadInt32( nFc ); | ||||||
2422 | pPLCF_PosArray[nIMax] = nFc; // end of the last Fkp | ||||||
2423 | |||||||
2424 | failure = bool(rSt.GetError()); | ||||||
2425 | } while(false); | ||||||
2426 | } | ||||||
2427 | |||||||
2428 | if (!failure) | ||||||
2429 | { | ||||||
2430 | // Pointer to content array | ||||||
2431 | pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]); | ||||||
2432 | sal_uInt8* p = pPLCF_Contents; | ||||||
2433 | |||||||
2434 | for (sal_Int32 i = 0; i < ncpN; ++i) // construct PNs | ||||||
2435 | { | ||||||
2436 | ShortToSVBT16(static_cast<sal_uInt16>(nPN + i), p); | ||||||
2437 | p += nStru; | ||||||
2438 | } | ||||||
2439 | } | ||||||
2440 | |||||||
2441 | SAL_WARN_IF(failure, "sw.ww8", "Document has corrupt PLCF, ignoring it")do { if (true && (failure)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "Document has corrupt PLCF, ignoring it" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2441" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has corrupt PLCF, ignoring it" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has corrupt PLCF, ignoring it"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2441" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Document has corrupt PLCF, ignoring it") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2441" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has corrupt PLCF, ignoring it" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has corrupt PLCF, ignoring it"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2441" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
2442 | |||||||
2443 | if (failure) | ||||||
2444 | MakeFailedPLCF(); | ||||||
2445 | } | ||||||
2446 | |||||||
2447 | bool WW8PLCF::SeekPos(WW8_CP nPos) | ||||||
2448 | { | ||||||
2449 | WW8_CP nP = nPos; | ||||||
2450 | |||||||
2451 | if( nP < pPLCF_PosArray[0] ) | ||||||
2452 | { | ||||||
2453 | nIdx = 0; | ||||||
2454 | // not found: nPos less than smallest entry | ||||||
2455 | return false; | ||||||
2456 | } | ||||||
2457 | |||||||
2458 | // Search from beginning? | ||||||
2459 | if ((nIdx < 1) || (nP < pPLCF_PosArray[nIdx - 1])) | ||||||
2460 | nIdx = 1; | ||||||
2461 | |||||||
2462 | sal_Int32 nI = nIdx; | ||||||
2463 | sal_Int32 nEnd = nIMax; | ||||||
2464 | |||||||
2465 | for(int n = (1==nIdx ? 1 : 2); n; --n ) | ||||||
2466 | { | ||||||
2467 | for( ; nI <=nEnd; ++nI) // search with an index that is incremented by 1 | ||||||
2468 | { | ||||||
2469 | if( nP < pPLCF_PosArray[nI] ) // found position | ||||||
2470 | { | ||||||
2471 | nIdx = nI - 1; // nI - 1 is the correct index | ||||||
2472 | return true; // done | ||||||
2473 | } | ||||||
2474 | } | ||||||
2475 | nI = 1; | ||||||
2476 | nEnd = nIdx-1; | ||||||
2477 | } | ||||||
2478 | |||||||
2479 | nIdx = nIMax; // not found, greater than all entries | ||||||
2480 | return false; | ||||||
2481 | } | ||||||
2482 | |||||||
2483 | bool WW8PLCF::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const | ||||||
2484 | { | ||||||
2485 | if ( nIdx >= nIMax ) | ||||||
2486 | { | ||||||
2487 | rStart = rEnd = WW8_CP_MAX; | ||||||
2488 | return false; | ||||||
2489 | } | ||||||
2490 | rStart = pPLCF_PosArray[ nIdx ]; | ||||||
2491 | rEnd = pPLCF_PosArray[ nIdx + 1 ]; | ||||||
2492 | rpValue = static_cast<void*>(&pPLCF_Contents[nIdx * nStru]); | ||||||
2493 | return true; | ||||||
2494 | } | ||||||
2495 | |||||||
2496 | WW8_CP WW8PLCF::Where() const | ||||||
2497 | { | ||||||
2498 | if ( nIdx >= nIMax ) | ||||||
2499 | return WW8_CP_MAX; | ||||||
2500 | |||||||
2501 | return pPLCF_PosArray[nIdx]; | ||||||
2502 | } | ||||||
2503 | |||||||
2504 | WW8PLCFpcd::WW8PLCFpcd(SvStream* pSt, sal_uInt32 nFilePos, | ||||||
2505 | sal_uInt32 nPLCF, sal_uInt32 nStruct) | ||||||
2506 | : nStru( nStruct ) | ||||||
2507 | { | ||||||
2508 | const sal_uInt32 nValidMin=4; | ||||||
2509 | |||||||
2510 | sal_uInt64 const nOldPos = pSt->Tell(); | ||||||
2511 | |||||||
2512 | bool bValid = checkSeek(*pSt, nFilePos); | ||||||
2513 | std::size_t nRemainingSize = pSt->remainingSize(); | ||||||
2514 | if( nRemainingSize < nValidMin || nPLCF < nValidMin ) | ||||||
2515 | bValid = false; | ||||||
2516 | nPLCF = bValid ? std::min(nRemainingSize, static_cast<std::size_t>(nPLCF)) : nValidMin; | ||||||
2517 | |||||||
2518 | pPLCF_PosArray.reset( new sal_Int32[ ( nPLCF + 3 ) / 4 ] ); // Pointer to Pos-array | ||||||
2519 | pPLCF_PosArray[0] = 0; | ||||||
2520 | |||||||
2521 | nPLCF = bValid ? pSt->ReadBytes(pPLCF_PosArray.get(), nPLCF) : nValidMin; | ||||||
2522 | nPLCF = std::max(nPLCF, nValidMin); | ||||||
2523 | |||||||
2524 | nIMax = ( nPLCF - 4 ) / ( 4 + nStruct ); | ||||||
2525 | #ifdef OSL_BIGENDIAN | ||||||
2526 | for( long nI = 0; nI <= nIMax; nI++ ) | ||||||
2527 | pPLCF_PosArray[nI] = OSL_SWAPDWORD( pPLCF_PosArray[nI] )((sal_uInt32)((((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16 )(((sal_uInt16)(((sal_uInt32)(pPLCF_PosArray[nI]) >> 16 ) & 0xFFFF))) >> 8) & 0xFF))) & 0xFF) | ((( sal_uInt16)(((sal_uInt8)((sal_uInt16)(((sal_uInt16)(((sal_uInt32 )(pPLCF_PosArray[nI]) >> 16) & 0xFFFF))) & 0xFF ))) & 0xFF) << 8)))) & 0xFFFF) | (((sal_uInt32) (((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16)(((sal_uInt16 )((sal_uInt32)(pPLCF_PosArray[nI]) & 0xFFFF))) >> 8 ) & 0xFF))) & 0xFF) | (((sal_uInt16)(((sal_uInt8)((sal_uInt16 )(((sal_uInt16)((sal_uInt32)(pPLCF_PosArray[nI]) & 0xFFFF ))) & 0xFF))) & 0xFF) << 8)))) & 0xFFFF) << 16)); | ||||||
2528 | #endif // OSL_BIGENDIAN | ||||||
2529 | |||||||
2530 | // Pointer to content array | ||||||
2531 | pPLCF_Contents = reinterpret_cast<sal_uInt8*>(&pPLCF_PosArray[nIMax + 1]); | ||||||
2532 | |||||||
2533 | pSt->Seek( nOldPos ); | ||||||
2534 | } | ||||||
2535 | |||||||
2536 | // If nStartPos < 0, the first element of PLCFs will be taken | ||||||
2537 | WW8PLCFpcd_Iter::WW8PLCFpcd_Iter( WW8PLCFpcd& rPLCFpcd, long nStartPos ) | ||||||
2538 | :rPLCF( rPLCFpcd ), nIdx( 0 ) | ||||||
2539 | { | ||||||
2540 | if( nStartPos >= 0 ) | ||||||
2541 | SeekPos( nStartPos ); | ||||||
2542 | } | ||||||
2543 | |||||||
2544 | bool WW8PLCFpcd_Iter::SeekPos(long nPos) | ||||||
2545 | { | ||||||
2546 | long nP = nPos; | ||||||
2547 | |||||||
2548 | if( nP < rPLCF.pPLCF_PosArray[0] ) | ||||||
2549 | { | ||||||
2550 | nIdx = 0; | ||||||
2551 | return false; // not found: nPos less than smallest entry | ||||||
2552 | } | ||||||
2553 | // Search from beginning? | ||||||
2554 | if ((nIdx < 1) || (nP < rPLCF.pPLCF_PosArray[nIdx - 1])) | ||||||
2555 | nIdx = 1; | ||||||
2556 | |||||||
2557 | long nI = nIdx; | ||||||
2558 | long nEnd = rPLCF.nIMax; | ||||||
2559 | |||||||
2560 | for(int n = (1==nIdx ? 1 : 2); n; --n ) | ||||||
2561 | { | ||||||
2562 | for( ; nI <=nEnd; ++nI) | ||||||
2563 | { // search with an index that is incremented by 1 | ||||||
2564 | if( nP < rPLCF.pPLCF_PosArray[nI] ) | ||||||
2565 | { // found position | ||||||
2566 | nIdx = nI - 1; // nI - 1 is the correct index | ||||||
2567 | return true; // done | ||||||
2568 | } | ||||||
2569 | } | ||||||
2570 | nI = 1; | ||||||
2571 | nEnd = nIdx-1; | ||||||
2572 | } | ||||||
2573 | nIdx = rPLCF.nIMax; // not found, greater than all entries | ||||||
2574 | return false; | ||||||
2575 | } | ||||||
2576 | |||||||
2577 | bool WW8PLCFpcd_Iter::Get(WW8_CP& rStart, WW8_CP& rEnd, void*& rpValue) const | ||||||
2578 | { | ||||||
2579 | if( nIdx >= rPLCF.nIMax ) | ||||||
2580 | { | ||||||
2581 | rStart = rEnd = WW8_CP_MAX; | ||||||
2582 | return false; | ||||||
2583 | } | ||||||
2584 | rStart = rPLCF.pPLCF_PosArray[nIdx]; | ||||||
2585 | rEnd = rPLCF.pPLCF_PosArray[nIdx + 1]; | ||||||
2586 | rpValue = static_cast<void*>(&rPLCF.pPLCF_Contents[nIdx * rPLCF.nStru]); | ||||||
2587 | return true; | ||||||
2588 | } | ||||||
2589 | |||||||
2590 | sal_Int32 WW8PLCFpcd_Iter::Where() const | ||||||
2591 | { | ||||||
2592 | if ( nIdx >= rPLCF.nIMax ) | ||||||
2593 | return SAL_MAX_INT32((sal_Int32) 0x7FFFFFFF); | ||||||
2594 | |||||||
2595 | return rPLCF.pPLCF_PosArray[nIdx]; | ||||||
2596 | } | ||||||
2597 | |||||||
2598 | bool WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator< | ||||||
2599 | (const WW8PLCFx_Fc_FKP::WW8Fkp::Entry& rSecond) const | ||||||
2600 | { | ||||||
2601 | return (mnFC < rSecond.mnFC); | ||||||
2602 | } | ||||||
2603 | |||||||
2604 | static bool IsReplaceAllSprm(sal_uInt16 nSpId) | ||||||
2605 | { | ||||||
2606 | return (NS_sprm::LN_PHugePapx == nSpId || 0x6646 == nSpId); | ||||||
2607 | } | ||||||
2608 | |||||||
2609 | static bool IsExpandableSprm(sal_uInt16 nSpId) | ||||||
2610 | { | ||||||
2611 | return 0x646B == nSpId; | ||||||
2612 | } | ||||||
2613 | |||||||
2614 | void WW8PLCFx_Fc_FKP::WW8Fkp::FillEntry(WW8PLCFx_Fc_FKP::WW8Fkp::Entry &rEntry, | ||||||
2615 | std::size_t nDataOffset, sal_uInt16 nLen) | ||||||
2616 | { | ||||||
2617 | bool bValidPos = (nDataOffset < sizeof(maRawData)); | ||||||
2618 | |||||||
2619 | OSL_ENSURE(bValidPos, "sprm sequence offset is out of range, ignoring")do { if (true && (!(bValidPos))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2619" ": "), "%s", "sprm sequence offset is out of range, ignoring" ); } } while (false); | ||||||
2620 | |||||||
2621 | if (!bValidPos) | ||||||
2622 | { | ||||||
2623 | rEntry.mnLen = 0; | ||||||
2624 | return; | ||||||
2625 | } | ||||||
2626 | |||||||
2627 | const sal_uInt16 nAvailableData = sizeof(maRawData)-nDataOffset; | ||||||
2628 | OSL_ENSURE(nLen <= nAvailableData, "srpm sequence len is out of range, clipping")do { if (true && (!(nLen <= nAvailableData))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2628" ": "), "%s", "srpm sequence len is out of range, clipping" ); } } while (false); | ||||||
2629 | rEntry.mnLen = std::min(nLen, nAvailableData); | ||||||
2630 | rEntry.mpData = maRawData + nDataOffset; | ||||||
2631 | } | ||||||
2632 | |||||||
2633 | WW8PLCFx_Fc_FKP::WW8Fkp::WW8Fkp(const WW8Fib& rFib, SvStream* pSt, | ||||||
2634 | SvStream* pDataSt, long _nFilePos, long nItemSiz, ePLCFT ePl, | ||||||
2635 | WW8_FC nStartFc) | ||||||
2636 | : nItemSize(nItemSiz), nFilePos(_nFilePos), mnIdx(0), ePLCF(ePl) | ||||||
2637 | , mnMustRemainCached(0), maSprmParser(rFib) | ||||||
2638 | { | ||||||
2639 | memset(maRawData, 0, 512); | ||||||
2640 | |||||||
2641 | const ww::WordVersion eVersion = rFib.GetFIBVersion(); | ||||||
2642 | |||||||
2643 | sal_uInt64 const nOldPos = pSt->Tell(); | ||||||
2644 | |||||||
2645 | bool bCouldSeek = checkSeek(*pSt, nFilePos); | ||||||
2646 | bool bCouldRead = bCouldSeek && checkRead(*pSt, maRawData, 512); | ||||||
2647 | |||||||
2648 | mnIMax = bCouldRead ? maRawData[511] : 0; | ||||||
2649 | |||||||
2650 | sal_uInt8 *pStart = maRawData; | ||||||
2651 | // Offset-Location in maRawData | ||||||
2652 | const size_t nRawDataStart = (mnIMax + 1) * 4; | ||||||
2653 | |||||||
2654 | for (mnIdx = 0; mnIdx < mnIMax; ++mnIdx) | ||||||
2655 | { | ||||||
2656 | const size_t nRawDataOffset = nRawDataStart + mnIdx * nItemSize; | ||||||
2657 | |||||||
2658 | //clip to available data, corrupt fkp | ||||||
2659 | if (nRawDataOffset >= 511) | ||||||
2660 | { | ||||||
2661 | mnIMax = mnIdx; | ||||||
2662 | break; | ||||||
2663 | } | ||||||
2664 | |||||||
2665 | unsigned int nOfs = maRawData[nRawDataOffset] * 2; | ||||||
2666 | // nOfs in [0..0xff*2=510] | ||||||
2667 | |||||||
2668 | Entry aEntry(Get_Long(pStart)); | ||||||
2669 | |||||||
2670 | if (nOfs) | ||||||
2671 | { | ||||||
2672 | switch (ePLCF) | ||||||
2673 | { | ||||||
2674 | case CHP: | ||||||
2675 | { | ||||||
2676 | aEntry.mnLen = maRawData[nOfs]; | ||||||
2677 | |||||||
2678 | //len byte | ||||||
2679 | std::size_t nDataOffset = nOfs + 1; | ||||||
2680 | |||||||
2681 | FillEntry(aEntry, nDataOffset, aEntry.mnLen); | ||||||
2682 | |||||||
2683 | if (aEntry.mnLen && eVersion <= ww::eWW2) | ||||||
2684 | { | ||||||
2685 | Word2CHPX aChpx = ReadWord2Chpx(*pSt, nFilePos + nOfs + 1, static_cast< sal_uInt8 >(aEntry.mnLen)); | ||||||
2686 | std::vector<sal_uInt8> aSprms = ChpxToSprms(aChpx); | ||||||
2687 | aEntry.mnLen = static_cast< sal_uInt16 >(aSprms.size()); | ||||||
2688 | if (aEntry.mnLen) | ||||||
2689 | { | ||||||
2690 | aEntry.mpData = new sal_uInt8[aEntry.mnLen]; | ||||||
2691 | memcpy(aEntry.mpData, aSprms.data(), aEntry.mnLen); | ||||||
2692 | aEntry.mbMustDelete = true; | ||||||
2693 | } | ||||||
2694 | } | ||||||
2695 | break; | ||||||
2696 | } | ||||||
2697 | case PAP: | ||||||
2698 | { | ||||||
2699 | sal_uInt8 nDelta = 0; | ||||||
2700 | |||||||
2701 | aEntry.mnLen = maRawData[nOfs]; | ||||||
2702 | if (IsEightPlus(eVersion) && !aEntry.mnLen) | ||||||
2703 | { | ||||||
2704 | aEntry.mnLen = maRawData[nOfs+1]; | ||||||
2705 | nDelta++; | ||||||
2706 | } | ||||||
2707 | aEntry.mnLen *= 2; | ||||||
2708 | |||||||
2709 | //stylecode, std/istd | ||||||
2710 | if (eVersion <= ww::eWW2) | ||||||
2711 | { | ||||||
2712 | if (aEntry.mnLen >= 1) | ||||||
2713 | { | ||||||
2714 | aEntry.mnIStd = *(maRawData+nOfs+1+nDelta); | ||||||
2715 | aEntry.mnLen--; //style code | ||||||
2716 | if (aEntry.mnLen >= 6) | ||||||
2717 | { | ||||||
2718 | aEntry.mnLen-=6; //PHE | ||||||
2719 | //skip stc, len byte + 6 byte PHE | ||||||
2720 | unsigned int nOffset = nOfs + 8; | ||||||
2721 | if (nOffset >= 511) //Bad offset | ||||||
2722 | aEntry.mnLen=0; | ||||||
2723 | if (aEntry.mnLen) //start is ok | ||||||
2724 | { | ||||||
2725 | if (nOffset + aEntry.mnLen > 512) //Bad end, clip | ||||||
2726 | aEntry.mnLen = 512 - nOffset; | ||||||
2727 | aEntry.mpData = maRawData + nOffset; | ||||||
2728 | } | ||||||
2729 | } | ||||||
2730 | else | ||||||
2731 | aEntry.mnLen=0; //Too short | ||||||
2732 | } | ||||||
2733 | } | ||||||
2734 | else | ||||||
2735 | { | ||||||
2736 | if (aEntry.mnLen >= 2) | ||||||
2737 | { | ||||||
2738 | //len byte + optional extra len byte | ||||||
2739 | std::size_t nDataOffset = nOfs + 1 + nDelta; | ||||||
2740 | aEntry.mnIStd = nDataOffset <= sizeof(maRawData)-sizeof(aEntry.mnIStd) ? | ||||||
2741 | SVBT16ToUInt16(maRawData+nDataOffset) : 0; | ||||||
2742 | aEntry.mnLen-=2; //istd | ||||||
2743 | if (aEntry.mnLen) | ||||||
2744 | { | ||||||
2745 | //additional istd | ||||||
2746 | nDataOffset += sizeof(aEntry.mnIStd); | ||||||
2747 | |||||||
2748 | FillEntry(aEntry, nDataOffset, aEntry.mnLen); | ||||||
2749 | } | ||||||
2750 | } | ||||||
2751 | else | ||||||
2752 | aEntry.mnLen=0; //Too short, ignore | ||||||
2753 | } | ||||||
2754 | |||||||
2755 | const sal_uInt16 nSpId = aEntry.mnLen | ||||||
2756 | ? maSprmParser.GetSprmId(aEntry.mpData) : 0; | ||||||
2757 | |||||||
2758 | /* | ||||||
2759 | If we replace then we throw away the old data, if we | ||||||
2760 | are expanding, then we tack the old data onto the end | ||||||
2761 | of the new data | ||||||
2762 | */ | ||||||
2763 | const bool bExpand = IsExpandableSprm(nSpId); | ||||||
2764 | const sal_uInt8* pStartData | ||||||
2765 | = aEntry.mpData == nullptr ? nullptr : aEntry.mpData + 2; | ||||||
2766 | const sal_uInt8* pLastValidDataPos = maRawData + 512 - sizeof(sal_uInt32); | ||||||
2767 | if (pStartData != nullptr && pStartData > pLastValidDataPos) | ||||||
2768 | pStartData = nullptr; | ||||||
2769 | if ((IsReplaceAllSprm(nSpId) || bExpand) && pStartData) | ||||||
2770 | { | ||||||
2771 | sal_uInt32 nCurr = pDataSt->Tell(); | ||||||
2772 | sal_uInt32 nPos = SVBT32ToUInt32(pStartData); | ||||||
2773 | sal_uInt16 nLen(0); | ||||||
2774 | |||||||
2775 | bool bOk = checkSeek(*pDataSt, nPos); | ||||||
2776 | if (bOk) | ||||||
2777 | { | ||||||
2778 | pDataSt->ReadUInt16( nLen ); | ||||||
2779 | bOk = nLen <= pDataSt->remainingSize(); | ||||||
2780 | } | ||||||
2781 | |||||||
2782 | if (bOk) | ||||||
2783 | { | ||||||
2784 | const sal_uInt16 nOrigLen = bExpand ? aEntry.mnLen : 0; | ||||||
2785 | sal_uInt8 *pOrigData = bExpand ? aEntry.mpData : nullptr; | ||||||
2786 | |||||||
2787 | aEntry.mnLen = nLen; | ||||||
2788 | aEntry.mpData = | ||||||
2789 | new sal_uInt8[aEntry.mnLen + nOrigLen]; | ||||||
2790 | aEntry.mbMustDelete = true; | ||||||
2791 | aEntry.mnLen = | ||||||
2792 | pDataSt->ReadBytes(aEntry.mpData, aEntry.mnLen); | ||||||
2793 | |||||||
2794 | pDataSt->Seek( nCurr ); | ||||||
2795 | |||||||
2796 | if (pOrigData) | ||||||
2797 | { | ||||||
2798 | memcpy(aEntry.mpData + aEntry.mnLen, | ||||||
2799 | pOrigData, nOrigLen); | ||||||
2800 | aEntry.mnLen = aEntry.mnLen + nOrigLen; | ||||||
2801 | } | ||||||
2802 | } | ||||||
2803 | } | ||||||
2804 | } | ||||||
2805 | break; | ||||||
2806 | default: | ||||||
2807 | OSL_FAIL("sweet god, what have you done!")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2807" ": "), "%s", "sweet god, what have you done!"); } } while (false); | ||||||
2808 | break; | ||||||
2809 | } | ||||||
2810 | } | ||||||
2811 | |||||||
2812 | maEntries.push_back(aEntry); | ||||||
2813 | |||||||
2814 | #ifdef DEBUGSPRMREADER | ||||||
2815 | { | ||||||
2816 | sal_Int32 nLen; | ||||||
2817 | sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen ); | ||||||
2818 | WW8SprmIter aIter(pSprms, nLen, maSprmParser); | ||||||
2819 | while (aIter.GetSprms()) | ||||||
2820 | { | ||||||
2821 | fprintf(stderrstderr, "id is %x\n", aIter.GetCurrentId()); | ||||||
2822 | aIter.advance(); | ||||||
2823 | } | ||||||
2824 | } | ||||||
2825 | #endif | ||||||
2826 | } | ||||||
2827 | |||||||
2828 | //one more FC than grrpl entries | ||||||
2829 | maEntries.emplace_back(Get_Long(pStart)); | ||||||
2830 | |||||||
2831 | //we expect them sorted, but it appears possible for them to arrive unsorted | ||||||
2832 | std::stable_sort(maEntries.begin(), maEntries.end()); | ||||||
2833 | |||||||
2834 | mnIdx = 0; | ||||||
2835 | |||||||
2836 | if (nStartFc >= 0) | ||||||
2837 | SeekPos(nStartFc); | ||||||
2838 | |||||||
2839 | pSt->Seek(nOldPos); | ||||||
2840 | } | ||||||
2841 | |||||||
2842 | WW8PLCFx_Fc_FKP::WW8Fkp::Entry::Entry(const Entry &rEntry) | ||||||
2843 | : mnFC(rEntry.mnFC), mnLen(rEntry.mnLen), mnIStd(rEntry.mnIStd), | ||||||
2844 | mbMustDelete(rEntry.mbMustDelete) | ||||||
2845 | { | ||||||
2846 | if (mbMustDelete) | ||||||
2847 | { | ||||||
2848 | mpData = new sal_uInt8[mnLen]; | ||||||
2849 | memcpy(mpData, rEntry.mpData, mnLen); | ||||||
2850 | } | ||||||
2851 | else | ||||||
2852 | mpData = rEntry.mpData; | ||||||
2853 | } | ||||||
2854 | |||||||
2855 | WW8PLCFx_Fc_FKP::WW8Fkp::Entry& | ||||||
2856 | WW8PLCFx_Fc_FKP::WW8Fkp::Entry::operator=(const Entry &rEntry) | ||||||
2857 | { | ||||||
2858 | if (this == &rEntry) | ||||||
2859 | return *this; | ||||||
2860 | |||||||
2861 | if (mbMustDelete) | ||||||
2862 | delete[] mpData; | ||||||
2863 | |||||||
2864 | mnFC = rEntry.mnFC; | ||||||
2865 | mnLen = rEntry.mnLen; | ||||||
2866 | mnIStd = rEntry.mnIStd; | ||||||
2867 | mbMustDelete = rEntry.mbMustDelete; | ||||||
2868 | |||||||
2869 | if (rEntry.mbMustDelete) | ||||||
2870 | { | ||||||
2871 | mpData = new sal_uInt8[mnLen]; | ||||||
2872 | memcpy(mpData, rEntry.mpData, mnLen); | ||||||
2873 | } | ||||||
2874 | else | ||||||
2875 | mpData = rEntry.mpData; | ||||||
2876 | |||||||
2877 | return *this; | ||||||
2878 | } | ||||||
2879 | |||||||
2880 | WW8PLCFx_Fc_FKP::WW8Fkp::Entry::~Entry() | ||||||
2881 | { | ||||||
2882 | if (mbMustDelete) | ||||||
2883 | delete[] mpData; | ||||||
2884 | } | ||||||
2885 | |||||||
2886 | void WW8PLCFx_Fc_FKP::WW8Fkp::Reset(WW8_FC nFc) | ||||||
2887 | { | ||||||
2888 | SetIdx(0); | ||||||
2889 | if (nFc >= 0) | ||||||
2890 | SeekPos(nFc); | ||||||
2891 | } | ||||||
2892 | |||||||
2893 | bool WW8PLCFx_Fc_FKP::WW8Fkp::SeekPos(WW8_FC nFc) | ||||||
2894 | { | ||||||
2895 | if (nFc < maEntries[0].mnFC) | ||||||
2896 | { | ||||||
2897 | mnIdx = 0; | ||||||
2898 | return false; // not found: nPos less than smallest entry | ||||||
2899 | } | ||||||
2900 | |||||||
2901 | // Search from beginning? | ||||||
2902 | if ((mnIdx < 1) || (nFc < maEntries[mnIdx - 1].mnFC)) | ||||||
2903 | mnIdx = 1; | ||||||
2904 | |||||||
2905 | sal_uInt8 nI = mnIdx; | ||||||
2906 | sal_uInt8 nEnd = mnIMax; | ||||||
2907 | |||||||
2908 | for(sal_uInt8 n = (1==mnIdx ? 1 : 2); n; --n ) | ||||||
2909 | { | ||||||
2910 | for( ; nI <=nEnd; ++nI) | ||||||
2911 | { // search with an index that is incremented by 1 | ||||||
2912 | if (nFc < maEntries[nI].mnFC) | ||||||
2913 | { // found position | ||||||
2914 | mnIdx = nI - 1; // nI - 1 is the correct index | ||||||
2915 | return true; // done | ||||||
2916 | } | ||||||
2917 | } | ||||||
2918 | nI = 1; | ||||||
2919 | nEnd = mnIdx-1; | ||||||
2920 | } | ||||||
2921 | mnIdx = mnIMax; // not found, greater than all entries | ||||||
2922 | return false; | ||||||
2923 | } | ||||||
2924 | |||||||
2925 | sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::Get(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen) | ||||||
2926 | const | ||||||
2927 | { | ||||||
2928 | rLen = 0; | ||||||
2929 | |||||||
2930 | if (mnIdx >= mnIMax) | ||||||
2931 | { | ||||||
2932 | rStart = WW8_FC_MAX; | ||||||
2933 | return nullptr; | ||||||
2934 | } | ||||||
2935 | |||||||
2936 | rStart = maEntries[mnIdx].mnFC; | ||||||
2937 | rEnd = maEntries[mnIdx + 1].mnFC; | ||||||
2938 | |||||||
2939 | sal_uInt8* pSprms = GetLenAndIStdAndSprms( rLen ); | ||||||
2940 | return pSprms; | ||||||
2941 | } | ||||||
2942 | |||||||
2943 | void WW8PLCFx_Fc_FKP::WW8Fkp::SetIdx(sal_uInt8 nI) | ||||||
2944 | { | ||||||
2945 | if (nI < mnIMax) | ||||||
2946 | { | ||||||
2947 | mnIdx = nI; | ||||||
2948 | } | ||||||
2949 | } | ||||||
2950 | |||||||
2951 | sal_uInt8* WW8PLCFx_Fc_FKP::WW8Fkp::GetLenAndIStdAndSprms(sal_Int32& rLen) const | ||||||
2952 | { | ||||||
2953 | rLen = maEntries[mnIdx].mnLen; | ||||||
2954 | return maEntries[mnIdx].mpData; | ||||||
2955 | } | ||||||
2956 | |||||||
2957 | SprmResult WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm( sal_uInt16 nId, bool bFindFirst ) | ||||||
2958 | { | ||||||
2959 | if (mnIdx >= mnIMax) | ||||||
2960 | return SprmResult(); | ||||||
2961 | |||||||
2962 | sal_Int32 nLen; | ||||||
2963 | sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen ); | ||||||
2964 | |||||||
2965 | WW8SprmIter aIter(pSprms, nLen, maSprmParser); | ||||||
2966 | return aIter.FindSprm(nId, bFindFirst); | ||||||
2967 | } | ||||||
2968 | |||||||
2969 | void WW8PLCFx_Fc_FKP::WW8Fkp::HasSprm(sal_uInt16 nId, | ||||||
2970 | std::vector<SprmResult> &rResult) | ||||||
2971 | { | ||||||
2972 | if (mnIdx >= mnIMax) | ||||||
2973 | return; | ||||||
2974 | |||||||
2975 | sal_Int32 nLen; | ||||||
2976 | sal_uInt8* pSprms = GetLenAndIStdAndSprms( nLen ); | ||||||
2977 | |||||||
2978 | WW8SprmIter aIter(pSprms, nLen, maSprmParser); | ||||||
2979 | |||||||
2980 | while(aIter.GetSprms()) | ||||||
2981 | { | ||||||
2982 | if (aIter.GetCurrentId() == nId) | ||||||
2983 | { | ||||||
2984 | sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId); | ||||||
2985 | sal_Int32 nL = maSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen()); | ||||||
2986 | rResult.emplace_back(aIter.GetCurrentParams(), nL - nFixedLen); | ||||||
2987 | } | ||||||
2988 | aIter.advance(); | ||||||
2989 | }; | ||||||
2990 | } | ||||||
2991 | |||||||
2992 | ww::WordVersion WW8PLCFx::GetFIBVersion() const | ||||||
2993 | { | ||||||
2994 | return mrFib.GetFIBVersion(); | ||||||
2995 | } | ||||||
2996 | |||||||
2997 | void WW8PLCFx::GetSprms( WW8PLCFxDesc* p ) | ||||||
2998 | { | ||||||
2999 | OSL_ENSURE( false, "Called wrong GetSprms" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "2999" ": "), "%s", "Called wrong GetSprms"); } } while ( false); | ||||||
3000 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
3001 | p->pMemPos = nullptr; | ||||||
3002 | p->nSprmsLen = 0; | ||||||
3003 | p->bRealLineEnd = false; | ||||||
3004 | } | ||||||
3005 | |||||||
3006 | long WW8PLCFx::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) | ||||||
3007 | { | ||||||
3008 | OSL_ENSURE( false, "Called wrong GetNoSprms" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3008" ": "), "%s", "Called wrong GetNoSprms"); } } while (false); | ||||||
3009 | rStart = rEnd = WW8_CP_MAX; | ||||||
3010 | rLen = 0; | ||||||
3011 | return 0; | ||||||
3012 | } | ||||||
3013 | |||||||
3014 | // ...Idx2: Default: ignore | ||||||
3015 | sal_uInt32 WW8PLCFx::GetIdx2() const | ||||||
3016 | { | ||||||
3017 | return 0; | ||||||
3018 | } | ||||||
3019 | |||||||
3020 | void WW8PLCFx::SetIdx2(sal_uInt32) | ||||||
3021 | { | ||||||
3022 | } | ||||||
3023 | |||||||
3024 | namespace { | ||||||
3025 | |||||||
3026 | class SamePos | ||||||
3027 | { | ||||||
3028 | private: | ||||||
3029 | long mnPo; | ||||||
3030 | public: | ||||||
3031 | explicit SamePos(long nPo) : mnPo(nPo) {} | ||||||
3032 | bool operator()(const std::unique_ptr<WW8PLCFx_Fc_FKP::WW8Fkp>& pFkp) | ||||||
3033 | {return mnPo == pFkp->GetFilePos();} | ||||||
3034 | }; | ||||||
3035 | |||||||
3036 | } | ||||||
3037 | |||||||
3038 | bool WW8PLCFx_Fc_FKP::NewFkp() | ||||||
3039 | { | ||||||
3040 | WW8_CP nPLCFStart, nPLCFEnd; | ||||||
3041 | void* pPage; | ||||||
3042 | |||||||
3043 | static const int WW8FkpSizeTabVer2[ PLCF_END ] = | ||||||
3044 | { | ||||||
3045 | 1, 1, 0 /*, 0, 0, 0*/ | ||||||
3046 | }; | ||||||
3047 | static const int WW8FkpSizeTabVer6[ PLCF_END ] = | ||||||
3048 | { | ||||||
3049 | 1, 7, 0 /*, 0, 0, 0*/ | ||||||
3050 | }; | ||||||
3051 | static const int WW8FkpSizeTabVer8[ PLCF_END ] = | ||||||
3052 | { | ||||||
3053 | 1, 13, 0 /*, 0, 0, 0*/ | ||||||
3054 | }; | ||||||
3055 | const int* pFkpSizeTab; | ||||||
3056 | |||||||
3057 | switch (GetFIBVersion()) | ||||||
3058 | { | ||||||
3059 | case ww::eWW1: | ||||||
3060 | case ww::eWW2: | ||||||
3061 | pFkpSizeTab = WW8FkpSizeTabVer2; | ||||||
3062 | break; | ||||||
3063 | case ww::eWW6: | ||||||
3064 | case ww::eWW7: | ||||||
3065 | pFkpSizeTab = WW8FkpSizeTabVer6; | ||||||
3066 | break; | ||||||
3067 | case ww::eWW8: | ||||||
3068 | pFkpSizeTab = WW8FkpSizeTabVer8; | ||||||
3069 | break; | ||||||
3070 | default: | ||||||
3071 | // program error! | ||||||
3072 | OSL_ENSURE( false, "nVersion not implemented!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3072" ": "), "%s", "nVersion not implemented!"); } } while (false); | ||||||
3073 | return false; | ||||||
3074 | } | ||||||
3075 | |||||||
3076 | if (!pPLCF->Get( nPLCFStart, nPLCFEnd, pPage )) | ||||||
3077 | { | ||||||
3078 | pFkp = nullptr; | ||||||
3079 | return false; // PLCF completely processed | ||||||
3080 | } | ||||||
3081 | pPLCF->advance(); | ||||||
3082 | long nPo = SVBT16ToUInt16( static_cast<sal_uInt8 *>(pPage) ); | ||||||
3083 | nPo <<= 9; // shift as LONG | ||||||
3084 | |||||||
3085 | long nCurrentFkpFilePos = pFkp ? pFkp->GetFilePos() : -1; | ||||||
3086 | if (nCurrentFkpFilePos == nPo) | ||||||
3087 | pFkp->Reset(GetStartFc()); | ||||||
3088 | else | ||||||
3089 | { | ||||||
3090 | auto aIter = | ||||||
3091 | std::find_if(maFkpCache.begin(), maFkpCache.end(), SamePos(nPo)); | ||||||
3092 | if (aIter != maFkpCache.end()) | ||||||
3093 | { | ||||||
3094 | pFkp = aIter->get(); | ||||||
3095 | pFkp->Reset(GetStartFc()); | ||||||
3096 | } | ||||||
3097 | else | ||||||
3098 | { | ||||||
3099 | pFkp = new WW8Fkp(GetFIB(), pFKPStrm, pDataStrm, nPo, | ||||||
3100 | pFkpSizeTab[ ePLCF ], ePLCF, GetStartFc()); | ||||||
3101 | maFkpCache.push_back(std::unique_ptr<WW8Fkp>(pFkp)); | ||||||
3102 | |||||||
3103 | if (maFkpCache.size() > eMaxCache) | ||||||
3104 | { | ||||||
3105 | WW8Fkp* pCachedFkp = maFkpCache.front().get(); | ||||||
3106 | if (!pCachedFkp->IsMustRemainCache()) | ||||||
3107 | { | ||||||
3108 | maFkpCache.pop_front(); | ||||||
3109 | } | ||||||
3110 | } | ||||||
3111 | } | ||||||
3112 | } | ||||||
3113 | |||||||
3114 | SetStartFc( -1 ); // only the first time | ||||||
3115 | return true; | ||||||
3116 | } | ||||||
3117 | |||||||
3118 | WW8PLCFx_Fc_FKP::WW8PLCFx_Fc_FKP(SvStream* pSt, SvStream* pTableSt, | ||||||
3119 | SvStream* pDataSt, const WW8Fib& rFib, ePLCFT ePl, WW8_FC nStartFcL) | ||||||
3120 | : WW8PLCFx(rFib, true), pFKPStrm(pSt), pDataStrm(pDataSt) | ||||||
3121 | , pFkp(nullptr), ePLCF(ePl) | ||||||
3122 | { | ||||||
3123 | SetStartFc(nStartFcL); | ||||||
3124 | long nLenStruct = (8 > rFib.m_nVersion) ? 2 : 4; | ||||||
3125 | if (ePl == CHP) | ||||||
3126 | { | ||||||
3127 | pPLCF.reset(new WW8PLCF(*pTableSt, rFib.m_fcPlcfbteChpx, rFib.m_lcbPlcfbteChpx, | ||||||
3128 | nLenStruct, GetStartFc(), rFib.m_pnChpFirst, rFib.m_cpnBteChp)); | ||||||
3129 | } | ||||||
3130 | else | ||||||
3131 | { | ||||||
3132 | pPLCF.reset(new WW8PLCF(*pTableSt, rFib.m_fcPlcfbtePapx, rFib.m_lcbPlcfbtePapx, | ||||||
3133 | nLenStruct, GetStartFc(), rFib.m_pnPapFirst, rFib.m_cpnBtePap)); | ||||||
3134 | } | ||||||
3135 | } | ||||||
3136 | |||||||
3137 | WW8PLCFx_Fc_FKP::~WW8PLCFx_Fc_FKP() | ||||||
3138 | { | ||||||
3139 | maFkpCache.clear(); | ||||||
3140 | pPLCF.reset(); | ||||||
3141 | pPCDAttrs.reset(); | ||||||
3142 | } | ||||||
3143 | |||||||
3144 | sal_uInt32 WW8PLCFx_Fc_FKP::GetIdx() const | ||||||
3145 | { | ||||||
3146 | sal_uInt32 u = pPLCF->GetIdx() << 8; | ||||||
3147 | if (pFkp) | ||||||
3148 | u |= pFkp->GetIdx(); | ||||||
3149 | return u; | ||||||
3150 | } | ||||||
3151 | |||||||
3152 | void WW8PLCFx_Fc_FKP::SetIdx(sal_uInt32 nIdx) | ||||||
3153 | { | ||||||
3154 | if( !( nIdx & 0xffffff00L ) ) | ||||||
3155 | { | ||||||
3156 | pPLCF->SetIdx( nIdx >> 8 ); | ||||||
3157 | pFkp = nullptr; | ||||||
3158 | } | ||||||
3159 | else | ||||||
3160 | { // there was a Fkp | ||||||
3161 | // Set PLCF one position back to retrieve the address of the Fkp | ||||||
3162 | pPLCF->SetIdx( ( nIdx >> 8 ) - 1 ); | ||||||
3163 | if (NewFkp()) // read Fkp again | ||||||
3164 | { | ||||||
3165 | sal_uInt8 nFkpIdx = static_cast<sal_uInt8>(nIdx & 0xff); | ||||||
3166 | pFkp->SetIdx(nFkpIdx); // set Fkp-Pos again | ||||||
3167 | } | ||||||
3168 | } | ||||||
3169 | } | ||||||
3170 | |||||||
3171 | bool WW8PLCFx_Fc_FKP::SeekPos(WW8_FC nFcPos) | ||||||
3172 | { | ||||||
3173 | // StartPos for next Where() | ||||||
3174 | SetStartFc( nFcPos ); | ||||||
3175 | |||||||
3176 | // find StartPos for next pPLCF->Get() | ||||||
3177 | bool bRet = pPLCF->SeekPos(nFcPos); | ||||||
3178 | |||||||
3179 | // make FKP invalid? | ||||||
3180 | WW8_CP nPLCFStart, nPLCFEnd; | ||||||
3181 | void* pPage; | ||||||
3182 | if( pFkp && pPLCF->Get( nPLCFStart, nPLCFEnd, pPage ) ) | ||||||
3183 | { | ||||||
3184 | long nPo = SVBT16ToUInt16( static_cast<sal_uInt8 *>(pPage) ); | ||||||
3185 | nPo <<= 9; // shift as LONG | ||||||
3186 | if (nPo != pFkp->GetFilePos()) | ||||||
3187 | pFkp = nullptr; | ||||||
3188 | else | ||||||
3189 | pFkp->SeekPos( nFcPos ); | ||||||
3190 | } | ||||||
3191 | return bRet; | ||||||
3192 | } | ||||||
3193 | |||||||
3194 | WW8_FC WW8PLCFx_Fc_FKP::Where() | ||||||
3195 | { | ||||||
3196 | if( !pFkp && !NewFkp() ) | ||||||
3197 | return WW8_FC_MAX; | ||||||
3198 | WW8_FC nP = pFkp ? pFkp->Where() : WW8_FC_MAX; | ||||||
3199 | if( nP != WW8_FC_MAX ) | ||||||
3200 | return nP; | ||||||
3201 | |||||||
3202 | pFkp = nullptr; // FKP finished -> get new | ||||||
3203 | return Where(); // easiest way: do it recursively | ||||||
3204 | } | ||||||
3205 | |||||||
3206 | sal_uInt8* WW8PLCFx_Fc_FKP::GetSprmsAndPos(WW8_FC& rStart, WW8_FC& rEnd, sal_Int32& rLen) | ||||||
3207 | { | ||||||
3208 | rLen = 0; // Default | ||||||
3209 | rStart = rEnd = WW8_FC_MAX; | ||||||
3210 | |||||||
3211 | if( !pFkp ) // Fkp not there ? | ||||||
3212 | { | ||||||
3213 | if( !NewFkp() ) | ||||||
3214 | return nullptr; | ||||||
3215 | } | ||||||
3216 | |||||||
3217 | sal_uInt8* pPos = pFkp ? pFkp->Get( rStart, rEnd, rLen ) : nullptr; | ||||||
3218 | if( rStart == WW8_FC_MAX ) //Not found | ||||||
3219 | return nullptr; | ||||||
3220 | return pPos; | ||||||
3221 | } | ||||||
3222 | |||||||
3223 | void WW8PLCFx_Fc_FKP::advance() | ||||||
3224 | { | ||||||
3225 | if( !pFkp && !NewFkp() ) | ||||||
3226 | return; | ||||||
3227 | |||||||
3228 | if (!pFkp) | ||||||
3229 | return; | ||||||
3230 | |||||||
3231 | pFkp->advance(); | ||||||
3232 | if( pFkp->Where() == WW8_FC_MAX ) | ||||||
3233 | (void)NewFkp(); | ||||||
3234 | } | ||||||
3235 | |||||||
3236 | sal_uInt16 WW8PLCFx_Fc_FKP::GetIstd() const | ||||||
3237 | { | ||||||
3238 | return pFkp ? pFkp->GetIstd() : 0xFFFF; | ||||||
3239 | } | ||||||
3240 | |||||||
3241 | void WW8PLCFx_Fc_FKP::GetPCDSprms( WW8PLCFxDesc& rDesc ) | ||||||
3242 | { | ||||||
3243 | rDesc.pMemPos = nullptr; | ||||||
3244 | rDesc.nSprmsLen = 0; | ||||||
3245 | if( pPCDAttrs ) | ||||||
3246 | { | ||||||
3247 | if( !pFkp ) | ||||||
3248 | { | ||||||
3249 | OSL_FAIL("+Problem: GetPCDSprms: NewFkp necessary (not possible!)" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3249" ": "), "%s", "+Problem: GetPCDSprms: NewFkp necessary (not possible!)" ); } } while (false); | ||||||
3250 | if( !NewFkp() ) | ||||||
3251 | return; | ||||||
3252 | } | ||||||
3253 | pPCDAttrs->GetSprms(&rDesc); | ||||||
3254 | } | ||||||
3255 | } | ||||||
3256 | |||||||
3257 | SprmResult WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, bool bFindFirst) | ||||||
3258 | { | ||||||
3259 | // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated | ||||||
3260 | if( !pFkp ) | ||||||
3261 | { | ||||||
3262 | OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3262" ": "), "%s", "+Motz: HasSprm: NewFkp needed ( no const possible )" ); } } while (false); | ||||||
3263 | // happens in BugDoc 31722 | ||||||
3264 | if( !NewFkp() ) | ||||||
3265 | return SprmResult(); | ||||||
3266 | } | ||||||
3267 | |||||||
3268 | if (!pFkp) | ||||||
3269 | return SprmResult(); | ||||||
3270 | |||||||
3271 | SprmResult aRes = pFkp->HasSprm(nId, bFindFirst); | ||||||
3272 | |||||||
3273 | if (!aRes.pSprm) | ||||||
3274 | { | ||||||
3275 | WW8PLCFxDesc aDesc; | ||||||
3276 | GetPCDSprms( aDesc ); | ||||||
3277 | |||||||
3278 | if (aDesc.pMemPos) | ||||||
3279 | { | ||||||
3280 | WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen, | ||||||
3281 | pFkp->GetSprmParser()); | ||||||
3282 | aRes = aIter.FindSprm(nId, bFindFirst); | ||||||
3283 | } | ||||||
3284 | } | ||||||
3285 | |||||||
3286 | return aRes; | ||||||
3287 | } | ||||||
3288 | |||||||
3289 | void WW8PLCFx_Fc_FKP::HasSprm(sal_uInt16 nId, std::vector<SprmResult> &rResult) | ||||||
3290 | { | ||||||
3291 | // const would be nicer, but for that, NewFkp() would need to be replaced or eliminated | ||||||
3292 | if (!pFkp) | ||||||
3293 | { | ||||||
3294 | OSL_FAIL( "+Motz: HasSprm: NewFkp needed ( no const possible )" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3294" ": "), "%s", "+Motz: HasSprm: NewFkp needed ( no const possible )" ); } } while (false); | ||||||
3295 | // happens in BugDoc 31722 | ||||||
3296 | if( !NewFkp() ) | ||||||
3297 | return; | ||||||
3298 | } | ||||||
3299 | |||||||
3300 | if (!pFkp) | ||||||
3301 | return; | ||||||
3302 | |||||||
3303 | pFkp->HasSprm(nId, rResult); | ||||||
3304 | |||||||
3305 | WW8PLCFxDesc aDesc; | ||||||
3306 | GetPCDSprms( aDesc ); | ||||||
3307 | |||||||
3308 | if (!aDesc.pMemPos) | ||||||
3309 | return; | ||||||
3310 | |||||||
3311 | const wwSprmParser &rSprmParser = pFkp->GetSprmParser(); | ||||||
3312 | WW8SprmIter aIter(aDesc.pMemPos, aDesc.nSprmsLen, rSprmParser); | ||||||
3313 | while(aIter.GetSprms()) | ||||||
3314 | { | ||||||
3315 | if (aIter.GetCurrentId() == nId) | ||||||
3316 | { | ||||||
3317 | sal_Int32 nFixedLen = rSprmParser.DistanceToData(nId); | ||||||
3318 | sal_Int32 nL = rSprmParser.GetSprmSize(nId, aIter.GetSprms(), aIter.GetRemLen()); | ||||||
3319 | rResult.emplace_back(aIter.GetCurrentParams(), nL - nFixedLen); | ||||||
3320 | } | ||||||
3321 | aIter.advance(); | ||||||
3322 | }; | ||||||
3323 | } | ||||||
3324 | |||||||
3325 | WW8PLCFx_Cp_FKP::WW8PLCFx_Cp_FKP( SvStream* pSt, SvStream* pTableSt, | ||||||
3326 | SvStream* pDataSt, const WW8ScannerBase& rBase, ePLCFT ePl ) | ||||||
3327 | : WW8PLCFx_Fc_FKP(pSt, pTableSt, pDataSt, *rBase.m_pWw8Fib, ePl, | ||||||
3328 | rBase.WW8Cp2Fc(0)), rSBase(rBase), nAttrStart(-1), nAttrEnd(-1), | ||||||
3329 | bLineEnd(false), | ||||||
3330 | bComplex( (7 < rBase.m_pWw8Fib->m_nVersion) || rBase.m_pWw8Fib->m_fComplex ) | ||||||
3331 | { | ||||||
3332 | ResetAttrStartEnd(); | ||||||
3333 | |||||||
3334 | if (rSBase.m_pPiecePLCF) | ||||||
3335 | pPcd.reset( new WW8PLCFx_PCD(GetFIB(), rBase.m_pPiecePLCF.get(), 0, IsSevenMinus(GetFIBVersion())) ); | ||||||
3336 | |||||||
3337 | /* | ||||||
3338 | Make a copy of the piece attributes for so that the calls to HasSprm on a | ||||||
3339 | Fc_FKP will be able to take into account the current piece attributes, | ||||||
3340 | despite the fact that such attributes can only be found through a cp based | ||||||
3341 | mechanism. | ||||||
3342 | */ | ||||||
3343 | if (pPcd) | ||||||
3344 | { | ||||||
3345 | pPCDAttrs.reset( rSBase.m_pPLCFx_PCDAttrs ? new WW8PLCFx_PCDAttrs( | ||||||
3346 | *rSBase.m_pWw8Fib, pPcd.get(), &rSBase) : nullptr); | ||||||
3347 | } | ||||||
3348 | |||||||
3349 | pPieceIter = rSBase.m_pPieceIter.get(); | ||||||
3350 | } | ||||||
3351 | |||||||
3352 | WW8PLCFx_Cp_FKP::~WW8PLCFx_Cp_FKP() | ||||||
3353 | { | ||||||
3354 | } | ||||||
3355 | |||||||
3356 | void WW8PLCFx_Cp_FKP::ResetAttrStartEnd() | ||||||
3357 | { | ||||||
3358 | nAttrStart = -1; | ||||||
3359 | nAttrEnd = -1; | ||||||
3360 | bLineEnd = false; | ||||||
3361 | } | ||||||
3362 | |||||||
3363 | sal_uInt32 WW8PLCFx_Cp_FKP::GetPCDIdx() const | ||||||
3364 | { | ||||||
3365 | return pPcd ? pPcd->GetIdx() : 0; | ||||||
3366 | } | ||||||
3367 | |||||||
3368 | bool WW8PLCFx_Cp_FKP::SeekPos(WW8_CP nCpPos) | ||||||
3369 | { | ||||||
3370 | if( pPcd ) // Complex | ||||||
3371 | { | ||||||
3372 | if( !pPcd->SeekPos( nCpPos ) ) // set piece | ||||||
3373 | return false; | ||||||
3374 | if (pPCDAttrs && !pPCDAttrs->GetIter()->SeekPos(nCpPos)) | ||||||
3375 | return false; | ||||||
3376 | return WW8PLCFx_Fc_FKP::SeekPos(pPcd->CurrentPieceStartCp2Fc(nCpPos)); | ||||||
3377 | } | ||||||
3378 | // NO piece table !!! | ||||||
3379 | return WW8PLCFx_Fc_FKP::SeekPos( rSBase.WW8Cp2Fc(nCpPos) ); | ||||||
3380 | } | ||||||
3381 | |||||||
3382 | WW8_CP WW8PLCFx_Cp_FKP::Where() | ||||||
3383 | { | ||||||
3384 | WW8_FC nFc = WW8PLCFx_Fc_FKP::Where(); | ||||||
3385 | if( pPcd ) | ||||||
3386 | return pPcd->CurrentPieceStartFc2Cp( nFc ); // identify piece | ||||||
3387 | return rSBase.WW8Fc2Cp( nFc ); // NO piece table !!! | ||||||
3388 | } | ||||||
3389 | |||||||
3390 | void WW8PLCFx_Cp_FKP::GetSprms(WW8PLCFxDesc* p) | ||||||
3391 | { | ||||||
3392 | WW8_CP nOrigCp = p->nStartPos; | ||||||
3393 | |||||||
3394 | if (!GetDirty()) //Normal case | ||||||
3395 | { | ||||||
3396 | p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(p->nStartPos, p->nEndPos, | ||||||
3397 | p->nSprmsLen); | ||||||
3398 | } | ||||||
3399 | else | ||||||
3400 | { | ||||||
3401 | /* | ||||||
3402 | For the odd case where we have a location in a fastsaved file which | ||||||
3403 | does not have an entry in the FKP, perhaps its para end is in the next | ||||||
3404 | piece, or perhaps the cp just doesn't exist at all in this document. | ||||||
3405 | AdvSprm doesn't know so it sets the PLCF as dirty and we figure out | ||||||
3406 | in this method what the situation is | ||||||
3407 | |||||||
3408 | It doesn't exist then the piece iterator will not be able to find it. | ||||||
3409 | Otherwise our cool fastsave algorithm can be brought to bear on the | ||||||
3410 | problem. | ||||||
3411 | */ | ||||||
3412 | if( !pPieceIter ) | ||||||
3413 | return; | ||||||
3414 | const sal_uInt32 nOldPos = pPieceIter->GetIdx(); | ||||||
3415 | bool bOk = pPieceIter->SeekPos(nOrigCp); | ||||||
3416 | pPieceIter->SetIdx(nOldPos); | ||||||
3417 | if (!bOk) | ||||||
3418 | return; | ||||||
3419 | } | ||||||
3420 | |||||||
3421 | if( pPcd ) // piece table available | ||||||
3422 | { | ||||||
3423 | // Init ( no ++ called, yet ) | ||||||
3424 | if( (nAttrStart > nAttrEnd) || (nAttrStart == -1) ) | ||||||
3425 | { | ||||||
3426 | p->bRealLineEnd = (ePLCF == PAP); | ||||||
3427 | |||||||
3428 | if ( ((ePLCF == PAP ) || (ePLCF == CHP)) && (nOrigCp != WW8_CP_MAX) ) | ||||||
3429 | { | ||||||
3430 | bool bIsUnicode=false; | ||||||
3431 | /* | ||||||
3432 | To find the end of a paragraph for a character in a | ||||||
3433 | complex format file. | ||||||
3434 | |||||||
3435 | It is necessary to know the piece that contains the | ||||||
3436 | character and the FC assigned to the character. | ||||||
3437 | */ | ||||||
3438 | |||||||
3439 | //We set the piece iterator to the piece that contains the | ||||||
3440 | //character, now we have the correct piece for this character | ||||||
3441 | sal_uInt32 nOldPos = pPieceIter->GetIdx(); | ||||||
3442 | p->nStartPos = nOrigCp; | ||||||
3443 | pPieceIter->SeekPos( p->nStartPos); | ||||||
3444 | |||||||
3445 | //This is the FC assigned to the character, but we already | ||||||
3446 | //have the result of the next stage, so we can skip this step | ||||||
3447 | //WW8_FC nStartFc = rSBase.WW8Cp2Fc(p->nStartPos, &bIsUnicode); | ||||||
3448 | |||||||
3449 | /* | ||||||
3450 | Using the FC of the character, first search the FKP that | ||||||
3451 | describes the character to find the smallest FC in the rgfc | ||||||
3452 | that is larger than the character FC. | ||||||
3453 | */ | ||||||
3454 | //But the search has already been done, the next largest FC is | ||||||
3455 | //p->nEndPos. | ||||||
3456 | WW8_FC nOldEndPos = p->nEndPos; | ||||||
3457 | |||||||
3458 | /* | ||||||
3459 | If the FC found in the FKP is less than or equal to the limit | ||||||
3460 | FC of the piece, the end of the paragraph that contains the | ||||||
3461 | character is at the FKP FC minus 1. | ||||||
3462 | */ | ||||||
3463 | WW8_CP nCpStart, nCpEnd; | ||||||
3464 | void* pData=nullptr; | ||||||
3465 | bool bOk = pPieceIter->Get(nCpStart, nCpEnd, pData); | ||||||
3466 | |||||||
3467 | if (!bOk) | ||||||
3468 | { | ||||||
3469 | pPieceIter->SetIdx(nOldPos); | ||||||
3470 | return; | ||||||
3471 | } | ||||||
3472 | |||||||
3473 | WW8_FC nLimitFC = SVBT32ToUInt32( static_cast<WW8_PCD*>(pData)->fc ); | ||||||
3474 | WW8_FC nBeginLimitFC = nLimitFC; | ||||||
3475 | if (IsEightPlus(GetFIBVersion())) | ||||||
3476 | { | ||||||
3477 | nBeginLimitFC = | ||||||
3478 | WW8PLCFx_PCD::TransformPieceAddress(nLimitFC, | ||||||
3479 | bIsUnicode); | ||||||
3480 | } | ||||||
3481 | |||||||
3482 | WW8_CP nCpLen; | ||||||
3483 | bool bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen); | ||||||
3484 | if (bFail) | ||||||
3485 | { | ||||||
3486 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3486" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3486" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3486" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3486" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3487 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3488 | pPieceIter->SetIdx(nOldPos); | ||||||
3489 | return; | ||||||
3490 | } | ||||||
3491 | |||||||
3492 | if (bIsUnicode) | ||||||
3493 | { | ||||||
3494 | bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen); | ||||||
3495 | if (bFail) | ||||||
3496 | { | ||||||
3497 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3497" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3497" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3497" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3497" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3498 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3499 | pPieceIter->SetIdx(nOldPos); | ||||||
3500 | return; | ||||||
3501 | } | ||||||
3502 | } | ||||||
3503 | |||||||
3504 | bFail = o3tl::checked_add(nBeginLimitFC, nCpLen, nLimitFC); | ||||||
3505 | if (bFail) | ||||||
3506 | { | ||||||
3507 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3507" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3507" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3507" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3507" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3508 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3509 | pPieceIter->SetIdx(nOldPos); | ||||||
3510 | return; | ||||||
3511 | } | ||||||
3512 | |||||||
3513 | if (nOldEndPos <= nLimitFC) | ||||||
3514 | { | ||||||
3515 | bFail = o3tl::checked_sub(nLimitFC, nOldEndPos, nCpLen); | ||||||
3516 | if (bFail) | ||||||
3517 | { | ||||||
3518 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3518" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3518" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3518" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3518" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3519 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3520 | pPieceIter->SetIdx(nOldPos); | ||||||
3521 | return; | ||||||
3522 | } | ||||||
3523 | |||||||
3524 | nCpLen /= (bIsUnicode ? 2 : 1); | ||||||
3525 | |||||||
3526 | bFail = o3tl::checked_sub(nCpEnd, nCpLen, p->nEndPos); | ||||||
3527 | if (bFail) | ||||||
3528 | { | ||||||
3529 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3529" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3529" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3529" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3529" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3530 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3531 | pPieceIter->SetIdx(nOldPos); | ||||||
3532 | return; | ||||||
3533 | } | ||||||
3534 | } | ||||||
3535 | else | ||||||
3536 | { | ||||||
3537 | if (ePLCF == CHP) | ||||||
3538 | p->nEndPos = nCpEnd; | ||||||
3539 | else | ||||||
3540 | { | ||||||
3541 | /* | ||||||
3542 | If the FKP FC that was found was greater than the FC | ||||||
3543 | of the end of the piece, scan piece by piece toward | ||||||
3544 | the end of the document until a piece is found that | ||||||
3545 | contains a paragraph end mark. | ||||||
3546 | */ | ||||||
3547 | |||||||
3548 | /* | ||||||
3549 | It's possible to check if a piece contains a paragraph | ||||||
3550 | mark by using the FC of the beginning of the piece to | ||||||
3551 | search in the FKPs for the smallest FC in the FKP rgfc | ||||||
3552 | that is greater than the FC of the beginning of the | ||||||
3553 | piece. If the FC found is less than or equal to the | ||||||
3554 | limit FC of the piece, then the character that ends | ||||||
3555 | the paragraph is the character immediately before the | ||||||
3556 | FKP fc | ||||||
3557 | */ | ||||||
3558 | |||||||
3559 | pPieceIter->advance(); | ||||||
3560 | |||||||
3561 | for (;pPieceIter->GetIdx() < pPieceIter->GetIMax(); | ||||||
3562 | pPieceIter->advance()) | ||||||
3563 | { | ||||||
3564 | if( !pPieceIter->Get( nCpStart, nCpEnd, pData ) ) | ||||||
3565 | { | ||||||
3566 | OSL_ENSURE( false, "piece iter broken!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3566" ": "), "%s", "piece iter broken!"); } } while (false ); | ||||||
3567 | break; | ||||||
3568 | } | ||||||
3569 | bIsUnicode = false; | ||||||
3570 | sal_Int32 nFcStart=SVBT32ToUInt32(static_cast<WW8_PCD*>(pData)->fc); | ||||||
3571 | |||||||
3572 | if (IsEightPlus(GetFIBVersion())) | ||||||
3573 | { | ||||||
3574 | nFcStart = | ||||||
3575 | WW8PLCFx_PCD::TransformPieceAddress( | ||||||
3576 | nFcStart,bIsUnicode ); | ||||||
3577 | } | ||||||
3578 | |||||||
3579 | bFail = o3tl::checked_sub(nCpEnd, nCpStart, nCpLen); | ||||||
3580 | if (bFail) | ||||||
3581 | { | ||||||
3582 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3582" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3582" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3582" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3582" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3583 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3584 | continue; | ||||||
3585 | } | ||||||
3586 | |||||||
3587 | if (bIsUnicode) | ||||||
3588 | { | ||||||
3589 | bFail = o3tl::checked_multiply<WW8_CP>(nCpLen, 2, nCpLen); | ||||||
3590 | if (bFail) | ||||||
3591 | { | ||||||
3592 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3592" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3592" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3592" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3592" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3593 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3594 | continue; | ||||||
3595 | } | ||||||
3596 | } | ||||||
3597 | |||||||
3598 | bFail = o3tl::checked_add(nFcStart, nCpLen, nLimitFC); | ||||||
3599 | if (bFail) | ||||||
3600 | { | ||||||
3601 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3601" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3601" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3601" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3601" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3602 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3603 | continue; | ||||||
3604 | } | ||||||
3605 | |||||||
3606 | //if it doesn't exist, skip it | ||||||
3607 | if (!SeekPos(nCpStart)) | ||||||
3608 | continue; | ||||||
3609 | |||||||
3610 | WW8_FC nOne,nSmallest; | ||||||
3611 | p->pMemPos = WW8PLCFx_Fc_FKP::GetSprmsAndPos(nOne, | ||||||
3612 | nSmallest, p->nSprmsLen); | ||||||
3613 | |||||||
3614 | if (nSmallest <= nLimitFC) | ||||||
3615 | { | ||||||
3616 | WW8_CP nCpDiff; | ||||||
3617 | bFail = o3tl::checked_sub(nLimitFC, nSmallest, nCpDiff); | ||||||
3618 | if (bFail) | ||||||
3619 | { | ||||||
3620 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3620" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3620" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3620" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3620" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3621 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3622 | continue; | ||||||
3623 | } | ||||||
3624 | if (bIsUnicode) | ||||||
3625 | nCpDiff /= 2; | ||||||
3626 | |||||||
3627 | WW8_CP nEndPos; | ||||||
3628 | bFail = o3tl::checked_sub(nCpEnd, nCpDiff, nEndPos); | ||||||
3629 | if (bFail) | ||||||
3630 | { | ||||||
3631 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3631" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3631" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3631" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3631" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3632 | p->nStartPos = p->nEndPos = WW8_FC_MAX; | ||||||
3633 | continue; | ||||||
3634 | } | ||||||
3635 | |||||||
3636 | OSL_ENSURE(nEndPos >= p->nStartPos, "EndPos before StartPos")do { if (true && (!(nEndPos >= p->nStartPos))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3636" ": "), "%s", "EndPos before StartPos"); } } while (false); | ||||||
3637 | |||||||
3638 | if (nEndPos >= p->nStartPos) | ||||||
3639 | p->nEndPos = nEndPos; | ||||||
3640 | |||||||
3641 | break; | ||||||
3642 | } | ||||||
3643 | } | ||||||
3644 | } | ||||||
3645 | } | ||||||
3646 | pPieceIter->SetIdx( nOldPos ); | ||||||
3647 | } | ||||||
3648 | else | ||||||
3649 | WW8PLCFx_PCD::CurrentPieceFc2Cp( p->nStartPos, p->nEndPos,&rSBase ); | ||||||
3650 | } | ||||||
3651 | else | ||||||
3652 | { | ||||||
3653 | p->nStartPos = nAttrStart; | ||||||
3654 | p->nEndPos = nAttrEnd; | ||||||
3655 | p->bRealLineEnd = bLineEnd; | ||||||
3656 | } | ||||||
3657 | } | ||||||
3658 | else // NO piece table !!! | ||||||
3659 | { | ||||||
3660 | p->nStartPos = rSBase.WW8Fc2Cp( p->nStartPos ); | ||||||
3661 | p->nEndPos = rSBase.WW8Fc2Cp( p->nEndPos ); | ||||||
3662 | p->bRealLineEnd = ePLCF == PAP; | ||||||
3663 | } | ||||||
3664 | } | ||||||
3665 | |||||||
3666 | void WW8PLCFx_Cp_FKP::advance() | ||||||
3667 | { | ||||||
3668 | WW8PLCFx_Fc_FKP::advance(); | ||||||
3669 | // !pPcd: emergency break | ||||||
3670 | if ( !bComplex || !pPcd ) | ||||||
3671 | return; | ||||||
3672 | |||||||
3673 | if( GetPCDIdx() >= pPcd->GetIMax() ) // End of PLCF | ||||||
3674 | { | ||||||
3675 | nAttrStart = nAttrEnd = WW8_CP_MAX; | ||||||
3676 | return; | ||||||
3677 | } | ||||||
3678 | |||||||
3679 | sal_Int32 nFkpLen; // Fkp entry | ||||||
3680 | // get Fkp entry | ||||||
3681 | WW8PLCFx_Fc_FKP::GetSprmsAndPos(nAttrStart, nAttrEnd, nFkpLen); | ||||||
3682 | |||||||
3683 | WW8PLCFx_PCD::CurrentPieceFc2Cp( nAttrStart, nAttrEnd, &rSBase ); | ||||||
3684 | bLineEnd = (ePLCF == PAP); | ||||||
3685 | } | ||||||
3686 | |||||||
3687 | WW8PLCFx_SEPX::WW8PLCFx_SEPX(SvStream* pSt, SvStream* pTableSt, | ||||||
3688 | const WW8Fib& rFib, WW8_CP nStartCp) | ||||||
3689 | : WW8PLCFx(rFib, true), maSprmParser(rFib), | ||||||
3690 | pStrm(pSt), nArrMax(256), nSprmSiz(0) | ||||||
3691 | { | ||||||
3692 | if (rFib.m_lcbPlcfsed) | ||||||
3693 | pPLCF.reset( new WW8PLCF(*pTableSt, rFib.m_fcPlcfsed, rFib.m_lcbPlcfsed, | ||||||
3694 | GetFIBVersion() <= ww::eWW2 ? 6 : 12, nStartCp) ); | ||||||
3695 | |||||||
3696 | pSprms.reset( new sal_uInt8[nArrMax] ); // maximum length | ||||||
3697 | } | ||||||
3698 | |||||||
3699 | WW8PLCFx_SEPX::~WW8PLCFx_SEPX() | ||||||
3700 | { | ||||||
3701 | } | ||||||
3702 | |||||||
3703 | sal_uInt32 WW8PLCFx_SEPX::GetIdx() const | ||||||
3704 | { | ||||||
3705 | return pPLCF ? pPLCF->GetIdx() : 0; | ||||||
3706 | } | ||||||
3707 | |||||||
3708 | void WW8PLCFx_SEPX::SetIdx(sal_uInt32 nIdx) | ||||||
3709 | { | ||||||
3710 | if( pPLCF ) pPLCF->SetIdx( nIdx ); | ||||||
3711 | } | ||||||
3712 | |||||||
3713 | bool WW8PLCFx_SEPX::SeekPos(WW8_CP nCpPos) | ||||||
3714 | { | ||||||
3715 | return pPLCF && pPLCF->SeekPos( nCpPos ); | ||||||
3716 | } | ||||||
3717 | |||||||
3718 | WW8_CP WW8PLCFx_SEPX::Where() | ||||||
3719 | { | ||||||
3720 | return pPLCF ? pPLCF->Where() : 0; | ||||||
3721 | } | ||||||
3722 | |||||||
3723 | void WW8PLCFx_SEPX::GetSprms(WW8PLCFxDesc* p) | ||||||
3724 | { | ||||||
3725 | if( !pPLCF ) return; | ||||||
3726 | |||||||
3727 | void* pData; | ||||||
3728 | |||||||
3729 | p->bRealLineEnd = false; | ||||||
3730 | if (!pPLCF->Get( p->nStartPos, p->nEndPos, pData )) | ||||||
3731 | { | ||||||
3732 | p->nStartPos = p->nEndPos = WW8_CP_MAX; // PLCF completely processed | ||||||
3733 | p->pMemPos = nullptr; | ||||||
3734 | p->nSprmsLen = 0; | ||||||
3735 | } | ||||||
3736 | else | ||||||
3737 | { | ||||||
3738 | sal_uInt32 nPo = SVBT32ToUInt32( static_cast<sal_uInt8*>(pData)+2 ); | ||||||
3739 | if (nPo == 0xFFFFFFFF || !checkSeek(*pStrm, nPo)) | ||||||
3740 | { | ||||||
3741 | p->nStartPos = p->nEndPos = WW8_CP_MAX; // Sepx empty | ||||||
3742 | p->pMemPos = nullptr; | ||||||
3743 | p->nSprmsLen = 0; | ||||||
3744 | } | ||||||
3745 | else | ||||||
3746 | { | ||||||
3747 | // read len | ||||||
3748 | if (GetFIBVersion() <= ww::eWW2) // eWW6 ?, docs say yes, but... | ||||||
3749 | { | ||||||
3750 | sal_uInt8 nSiz(0); | ||||||
3751 | pStrm->ReadUChar( nSiz ); | ||||||
3752 | nSprmSiz = nSiz; | ||||||
3753 | } | ||||||
3754 | else | ||||||
3755 | { | ||||||
3756 | pStrm->ReadUInt16( nSprmSiz ); | ||||||
3757 | } | ||||||
3758 | |||||||
3759 | std::size_t nRemaining = pStrm->remainingSize(); | ||||||
3760 | if (nSprmSiz > nRemaining) | ||||||
3761 | nSprmSiz = nRemaining; | ||||||
3762 | |||||||
3763 | if( nSprmSiz > nArrMax ) | ||||||
3764 | { // does not fit | ||||||
3765 | nArrMax = nSprmSiz; // Get more memory | ||||||
3766 | pSprms.reset( new sal_uInt8[nArrMax] ); | ||||||
3767 | } | ||||||
3768 | nSprmSiz = pStrm->ReadBytes(pSprms.get(), nSprmSiz); // read Sprms | ||||||
3769 | |||||||
3770 | p->nSprmsLen = nSprmSiz; | ||||||
3771 | p->pMemPos = pSprms.get(); // return Position | ||||||
3772 | } | ||||||
3773 | } | ||||||
3774 | } | ||||||
3775 | |||||||
3776 | void WW8PLCFx_SEPX::advance() | ||||||
3777 | { | ||||||
3778 | if (pPLCF) | ||||||
3779 | pPLCF->advance(); | ||||||
3780 | } | ||||||
3781 | |||||||
3782 | SprmResult WW8PLCFx_SEPX::HasSprm(sal_uInt16 nId) const | ||||||
3783 | { | ||||||
3784 | return HasSprm(nId, pSprms.get(), nSprmSiz); | ||||||
3785 | } | ||||||
3786 | |||||||
3787 | SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, const sal_uInt8* pOtherSprms, | ||||||
3788 | long nOtherSprmSiz ) const | ||||||
3789 | { | ||||||
3790 | SprmResult aRet; | ||||||
3791 | if (pPLCF) | ||||||
3792 | { | ||||||
3793 | WW8SprmIter aIter(pOtherSprms, nOtherSprmSiz, maSprmParser); | ||||||
3794 | aRet = aIter.FindSprm(nId, /*bFindFirst=*/true); | ||||||
3795 | } | ||||||
3796 | return aRet; | ||||||
3797 | } | ||||||
3798 | |||||||
3799 | bool WW8PLCFx_SEPX::Find4Sprms(sal_uInt16 nId1,sal_uInt16 nId2,sal_uInt16 nId3,sal_uInt16 nId4, | ||||||
3800 | SprmResult& r1, SprmResult& r2, SprmResult& r3, SprmResult& r4) const | ||||||
3801 | { | ||||||
3802 | if( !pPLCF ) | ||||||
3803 | return false; | ||||||
3804 | |||||||
3805 | bool bFound = false; | ||||||
3806 | |||||||
3807 | sal_uInt8* pSp = pSprms.get(); | ||||||
3808 | size_t i = 0; | ||||||
3809 | while (i + maSprmParser.MinSprmLen() <= nSprmSiz) | ||||||
3810 | { | ||||||
3811 | // Sprm found? | ||||||
3812 | const sal_uInt16 nCurrentId = maSprmParser.GetSprmId(pSp); | ||||||
3813 | sal_Int32 nRemLen = nSprmSiz - i; | ||||||
3814 | const sal_Int32 x = maSprmParser.GetSprmSize(nCurrentId, pSp, nRemLen); | ||||||
3815 | bool bValid = x <= nRemLen; | ||||||
3816 | if (!bValid) | ||||||
3817 | { | ||||||
3818 | SAL_WARN("sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3818" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3818" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3818" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3818" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3819 | break; | ||||||
3820 | } | ||||||
3821 | bool bOk = true; | ||||||
3822 | if( nCurrentId == nId1 ) | ||||||
3823 | { | ||||||
3824 | sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId1); | ||||||
3825 | r1 = SprmResult(pSp + nFixedLen, x - nFixedLen); | ||||||
3826 | } | ||||||
3827 | else if( nCurrentId == nId2 ) | ||||||
3828 | { | ||||||
3829 | sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId2); | ||||||
3830 | r2 = SprmResult(pSp + nFixedLen, x - nFixedLen); | ||||||
3831 | } | ||||||
3832 | else if( nCurrentId == nId3 ) | ||||||
3833 | { | ||||||
3834 | sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId3); | ||||||
3835 | r3 = SprmResult(pSp + nFixedLen, x - nFixedLen); | ||||||
3836 | } | ||||||
3837 | else if( nCurrentId == nId4 ) | ||||||
3838 | { | ||||||
3839 | sal_Int32 nFixedLen = maSprmParser.DistanceToData(nId4); | ||||||
3840 | r4 = SprmResult(pSp + nFixedLen, x - nFixedLen); | ||||||
3841 | } | ||||||
3842 | else | ||||||
3843 | bOk = false; | ||||||
3844 | bFound |= bOk; | ||||||
3845 | // increment pointer so that it points to next SPRM | ||||||
3846 | i += x; | ||||||
3847 | pSp += x; | ||||||
3848 | } | ||||||
3849 | return bFound; | ||||||
3850 | } | ||||||
3851 | |||||||
3852 | SprmResult WW8PLCFx_SEPX::HasSprm( sal_uInt16 nId, sal_uInt8 n2nd ) const | ||||||
3853 | { | ||||||
3854 | SprmResult aRet; | ||||||
3855 | if (pPLCF) | ||||||
3856 | { | ||||||
3857 | WW8SprmIter aIter(pSprms.get(), nSprmSiz, maSprmParser); | ||||||
3858 | aRet = aIter.FindSprm(nId, /*bFindFirst=*/true, &n2nd); | ||||||
3859 | } | ||||||
3860 | return aRet; | ||||||
3861 | } | ||||||
3862 | |||||||
3863 | WW8PLCFx_SubDoc::WW8PLCFx_SubDoc(SvStream* pSt, const WW8Fib& rFib, | ||||||
3864 | WW8_CP nStartCp, long nFcRef, long nLenRef, long nFcText, long nLenText, | ||||||
3865 | long nStruct) | ||||||
3866 | : WW8PLCFx(rFib, true) | ||||||
3867 | { | ||||||
3868 | if( nLenRef && nLenText ) | ||||||
3869 | { | ||||||
3870 | pRef.reset(new WW8PLCF(*pSt, nFcRef, nLenRef, nStruct, nStartCp)); | ||||||
3871 | pText.reset(new WW8PLCF(*pSt, nFcText, nLenText, 0, nStartCp)); | ||||||
3872 | } | ||||||
3873 | } | ||||||
3874 | |||||||
3875 | WW8PLCFx_SubDoc::~WW8PLCFx_SubDoc() | ||||||
3876 | { | ||||||
3877 | pRef.reset(); | ||||||
3878 | pText.reset(); | ||||||
3879 | } | ||||||
3880 | |||||||
3881 | sal_uInt32 WW8PLCFx_SubDoc::GetIdx() const | ||||||
3882 | { | ||||||
3883 | // Probably pText ... no need for it | ||||||
3884 | if( pRef ) | ||||||
3885 | return ( pRef->GetIdx() << 16 | pText->GetIdx() ); | ||||||
3886 | return 0; | ||||||
3887 | } | ||||||
3888 | |||||||
3889 | void WW8PLCFx_SubDoc::SetIdx(sal_uInt32 nIdx) | ||||||
3890 | { | ||||||
3891 | if( pRef ) | ||||||
3892 | { | ||||||
3893 | pRef->SetIdx( nIdx >> 16 ); | ||||||
3894 | // Probably pText ... no need for it | ||||||
3895 | pText->SetIdx( nIdx & 0xFFFF ); | ||||||
3896 | } | ||||||
3897 | } | ||||||
3898 | |||||||
3899 | bool WW8PLCFx_SubDoc::SeekPos( WW8_CP nCpPos ) | ||||||
3900 | { | ||||||
3901 | return pRef && pRef->SeekPos( nCpPos ); | ||||||
3902 | } | ||||||
3903 | |||||||
3904 | WW8_CP WW8PLCFx_SubDoc::Where() | ||||||
3905 | { | ||||||
3906 | return pRef ? pRef->Where() : WW8_CP_MAX; | ||||||
3907 | } | ||||||
3908 | |||||||
3909 | void WW8PLCFx_SubDoc::GetSprms(WW8PLCFxDesc* p) | ||||||
3910 | { | ||||||
3911 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
3912 | p->pMemPos = nullptr; | ||||||
3913 | p->nSprmsLen = 0; | ||||||
3914 | p->bRealLineEnd = false; | ||||||
3915 | |||||||
3916 | if (!pRef) | ||||||
3917 | return; | ||||||
3918 | |||||||
3919 | sal_uInt32 nNr = pRef->GetIdx(); | ||||||
3920 | |||||||
3921 | void *pData; | ||||||
3922 | WW8_CP nFoo; | ||||||
3923 | if (!pRef->Get(p->nStartPos, nFoo, pData)) | ||||||
3924 | { | ||||||
3925 | p->nEndPos = p->nStartPos = WW8_CP_MAX; | ||||||
3926 | return; | ||||||
3927 | } | ||||||
3928 | |||||||
3929 | if (o3tl::checked_add<WW8_CP>(p->nStartPos, 1, p->nEndPos)) | ||||||
3930 | { | ||||||
3931 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3931" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3931" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3931" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3931" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3932 | p->nEndPos = p->nStartPos = WW8_CP_MAX; | ||||||
3933 | return; | ||||||
3934 | } | ||||||
3935 | |||||||
3936 | if (!pText) | ||||||
3937 | return; | ||||||
3938 | |||||||
3939 | pText->SetIdx(nNr); | ||||||
3940 | |||||||
3941 | if (!pText->Get(p->nCp2OrIdx, p->nSprmsLen, pData)) | ||||||
3942 | { | ||||||
3943 | p->nEndPos = p->nStartPos = WW8_CP_MAX; | ||||||
3944 | p->nSprmsLen = 0; | ||||||
3945 | return; | ||||||
3946 | } | ||||||
3947 | |||||||
3948 | if (p->nCp2OrIdx < 0 || p->nCp2OrIdx > p->nSprmsLen) | ||||||
3949 | { | ||||||
3950 | SAL_WARN("sw.ww8", "Document has invalid Cp or Idx, ignoring it")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Document has invalid Cp or Idx, ignoring it" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3950" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has invalid Cp or Idx, ignoring it" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has invalid Cp or Idx, ignoring it"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3950" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Document has invalid Cp or Idx, ignoring it") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3950" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Document has invalid Cp or Idx, ignoring it" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Document has invalid Cp or Idx, ignoring it"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "3950" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
3951 | p->nEndPos = p->nStartPos = WW8_CP_MAX; | ||||||
3952 | p->nSprmsLen = 0; | ||||||
3953 | return; | ||||||
3954 | } | ||||||
3955 | |||||||
3956 | p->nSprmsLen -= p->nCp2OrIdx; | ||||||
3957 | } | ||||||
3958 | |||||||
3959 | void WW8PLCFx_SubDoc::advance() | ||||||
3960 | { | ||||||
3961 | if (pRef && pText) | ||||||
3962 | { | ||||||
3963 | pRef->advance(); | ||||||
3964 | pText->advance(); | ||||||
3965 | } | ||||||
3966 | } | ||||||
3967 | |||||||
3968 | // fields | ||||||
3969 | WW8PLCFx_FLD::WW8PLCFx_FLD( SvStream* pSt, const WW8Fib& rMyFib, short nType) | ||||||
3970 | : WW8PLCFx(rMyFib, true), rFib(rMyFib) | ||||||
3971 | { | ||||||
3972 | WW8_FC nFc; | ||||||
3973 | sal_Int32 nLen; | ||||||
3974 | |||||||
3975 | switch( nType ) | ||||||
3976 | { | ||||||
3977 | case MAN_HDFT: | ||||||
3978 | nFc = rFib.m_fcPlcffldHdr; | ||||||
3979 | nLen = rFib.m_lcbPlcffldHdr; | ||||||
3980 | break; | ||||||
3981 | case MAN_FTN: | ||||||
3982 | nFc = rFib.m_fcPlcffldFootnote; | ||||||
3983 | nLen = rFib.m_lcbPlcffldFootnote; | ||||||
3984 | break; | ||||||
3985 | case MAN_EDN: | ||||||
3986 | nFc = rFib.m_fcPlcffldEdn; | ||||||
3987 | nLen = rFib.m_lcbPlcffldEdn; | ||||||
3988 | break; | ||||||
3989 | case MAN_AND: | ||||||
3990 | nFc = rFib.m_fcPlcffldAtn; | ||||||
3991 | nLen = rFib.m_lcbPlcffldAtn; | ||||||
3992 | break; | ||||||
3993 | case MAN_TXBX: | ||||||
3994 | nFc = rFib.m_fcPlcffldTxbx; | ||||||
3995 | nLen = rFib.m_lcbPlcffldTxbx; | ||||||
3996 | break; | ||||||
3997 | case MAN_TXBX_HDFT: | ||||||
3998 | nFc = rFib.m_fcPlcffldHdrTxbx; | ||||||
3999 | nLen = rFib.m_lcbPlcffldHdrTxbx; | ||||||
4000 | break; | ||||||
4001 | default: | ||||||
4002 | nFc = rFib.m_fcPlcffldMom; | ||||||
4003 | nLen = rFib.m_lcbPlcffldMom; | ||||||
4004 | break; | ||||||
4005 | } | ||||||
4006 | |||||||
4007 | if( nLen ) | ||||||
4008 | pPLCF.reset( new WW8PLCFspecial( pSt, nFc, nLen, 2 ) ); | ||||||
4009 | } | ||||||
4010 | |||||||
4011 | WW8PLCFx_FLD::~WW8PLCFx_FLD() | ||||||
4012 | { | ||||||
4013 | } | ||||||
4014 | |||||||
4015 | sal_uInt32 WW8PLCFx_FLD::GetIdx() const | ||||||
4016 | { | ||||||
4017 | return pPLCF ? pPLCF->GetIdx() : 0; | ||||||
4018 | } | ||||||
4019 | |||||||
4020 | void WW8PLCFx_FLD::SetIdx(sal_uInt32 nIdx) | ||||||
4021 | { | ||||||
4022 | if( pPLCF ) | ||||||
4023 | pPLCF->SetIdx( nIdx ); | ||||||
4024 | } | ||||||
4025 | |||||||
4026 | bool WW8PLCFx_FLD::SeekPos(WW8_CP nCpPos) | ||||||
4027 | { | ||||||
4028 | return pPLCF && pPLCF->SeekPosExact( nCpPos ); | ||||||
4029 | } | ||||||
4030 | |||||||
4031 | WW8_CP WW8PLCFx_FLD::Where() | ||||||
4032 | { | ||||||
4033 | return pPLCF ? pPLCF->Where() : WW8_CP_MAX; | ||||||
4034 | } | ||||||
4035 | |||||||
4036 | bool WW8PLCFx_FLD::StartPosIsFieldStart() | ||||||
4037 | { | ||||||
4038 | void* pData; | ||||||
4039 | sal_Int32 nTest; | ||||||
4040 | return pPLCF && pPLCF->Get(nTest, pData) && ((static_cast<sal_uInt8*>(pData)[0] & 0x1f) == 0x13); | ||||||
4041 | } | ||||||
4042 | |||||||
4043 | bool WW8PLCFx_FLD::EndPosIsFieldEnd(WW8_CP& nCP) | ||||||
4044 | { | ||||||
4045 | bool bRet = false; | ||||||
4046 | |||||||
4047 | if (pPLCF) | ||||||
4048 | { | ||||||
4049 | long n = pPLCF->GetIdx(); | ||||||
4050 | |||||||
4051 | pPLCF->advance(); | ||||||
4052 | |||||||
4053 | void* pData; | ||||||
4054 | sal_Int32 nTest; | ||||||
4055 | if ( pPLCF->Get(nTest, pData) && ((static_cast<sal_uInt8*>(pData)[0] & 0x1f) == 0x15) ) | ||||||
4056 | { | ||||||
4057 | nCP = nTest; | ||||||
4058 | bRet = true; | ||||||
4059 | } | ||||||
4060 | |||||||
4061 | pPLCF->SetIdx(n); | ||||||
4062 | } | ||||||
4063 | |||||||
4064 | return bRet; | ||||||
4065 | } | ||||||
4066 | |||||||
4067 | void WW8PLCFx_FLD::GetSprms(WW8PLCFxDesc* p) | ||||||
4068 | { | ||||||
4069 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
4070 | p->pMemPos = nullptr; | ||||||
4071 | p->nSprmsLen = 0; | ||||||
4072 | p->bRealLineEnd = false; | ||||||
4073 | |||||||
4074 | if (!pPLCF) | ||||||
4075 | { | ||||||
4076 | p->nStartPos = WW8_CP_MAX; // there are no fields | ||||||
4077 | return; | ||||||
4078 | } | ||||||
4079 | |||||||
4080 | long n = pPLCF->GetIdx(); | ||||||
4081 | |||||||
4082 | sal_Int32 nP; | ||||||
4083 | void *pData; | ||||||
4084 | if (!pPLCF->Get(nP, pData)) // end of PLCFspecial? | ||||||
4085 | { | ||||||
4086 | p->nStartPos = WW8_CP_MAX; // PLCF completely processed | ||||||
4087 | return; | ||||||
4088 | } | ||||||
4089 | |||||||
4090 | p->nStartPos = nP; | ||||||
4091 | |||||||
4092 | pPLCF->advance(); | ||||||
4093 | if (!pPLCF->Get(nP, pData)) // end of PLCFspecial? | ||||||
4094 | { | ||||||
4095 | p->nStartPos = WW8_CP_MAX; // PLCF completely processed | ||||||
4096 | return; | ||||||
4097 | } | ||||||
4098 | |||||||
4099 | p->nEndPos = nP; | ||||||
4100 | |||||||
4101 | pPLCF->SetIdx(n); | ||||||
4102 | |||||||
4103 | p->nCp2OrIdx = pPLCF->GetIdx(); | ||||||
4104 | } | ||||||
4105 | |||||||
4106 | void WW8PLCFx_FLD::advance() | ||||||
4107 | { | ||||||
4108 | SAL_WARN_IF(!pPLCF, "sw.ww8", "Call without PLCFspecial field")do { if (true && (!pPLCF)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "Call without PLCFspecial field" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4108" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Call without PLCFspecial field"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Call without PLCFspecial field"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4108" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Call without PLCFspecial field") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4108" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Call without PLCFspecial field"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Call without PLCFspecial field"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4108" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4109 | if( !pPLCF ) | ||||||
4110 | return; | ||||||
4111 | pPLCF->advance(); | ||||||
4112 | } | ||||||
4113 | |||||||
4114 | bool WW8PLCFx_FLD::GetPara(long nIdx, WW8FieldDesc& rF) | ||||||
4115 | { | ||||||
4116 | SAL_WARN_IF(!pPLCF, "sw.ww8", "Call without PLCFspecial field")do { if (true && (!pPLCF)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "Call without PLCFspecial field" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4116" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Call without PLCFspecial field"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Call without PLCFspecial field"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4116" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Call without PLCFspecial field") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4116" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Call without PLCFspecial field"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Call without PLCFspecial field"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4116" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
| |||||||
4117 | if( !pPLCF ) | ||||||
4118 | return false; | ||||||
4119 | |||||||
4120 | long n = pPLCF->GetIdx(); | ||||||
4121 | pPLCF->SetIdx(nIdx); | ||||||
4122 | |||||||
4123 | bool bOk = WW8GetFieldPara(*pPLCF, rF); | ||||||
4124 | |||||||
4125 | pPLCF->SetIdx(n); | ||||||
4126 | return bOk; | ||||||
4127 | } | ||||||
4128 | |||||||
4129 | // WW8PLCF_Book | ||||||
4130 | void WW8ReadSTTBF(bool bVer8, SvStream& rStrm, sal_uInt32 nStart, sal_Int32 nLen, | ||||||
4131 | sal_uInt16 nExtraLen, rtl_TextEncoding eCS, std::vector<OUString> &rArray, | ||||||
4132 | std::vector<ww::bytes>* pExtraArray, std::vector<OUString>* pValueArray) | ||||||
4133 | { | ||||||
4134 | if (nLen==0) // Handle Empty STTBF | ||||||
4135 | return; | ||||||
4136 | |||||||
4137 | sal_uInt64 const nOldPos = rStrm.Tell(); | ||||||
4138 | if (checkSeek(rStrm, nStart)) | ||||||
4139 | { | ||||||
4140 | sal_uInt16 nLen2(0); | ||||||
4141 | rStrm.ReadUInt16( nLen2 ); // bVer67: total length of structure | ||||||
4142 | // bVer8 : count of strings | ||||||
4143 | |||||||
4144 | if( bVer8 ) | ||||||
4145 | { | ||||||
4146 | sal_uInt16 nStrings(0); | ||||||
4147 | bool bUnicode = (0xFFFF == nLen2); | ||||||
4148 | if (bUnicode) | ||||||
4149 | rStrm.ReadUInt16( nStrings ); | ||||||
4150 | else | ||||||
4151 | nStrings = nLen2; | ||||||
4152 | |||||||
4153 | rStrm.ReadUInt16( nExtraLen ); | ||||||
4154 | |||||||
4155 | const size_t nMinStringLen = bUnicode ? sizeof(sal_uInt16) : sizeof(sal_uInt8); | ||||||
4156 | const size_t nMinRecordSize = nExtraLen + nMinStringLen; | ||||||
4157 | const size_t nMaxPossibleStrings = rStrm.remainingSize() / nMinRecordSize; | ||||||
4158 | if (nStrings > nMaxPossibleStrings) | ||||||
4159 | { | ||||||
4160 | SAL_WARN("sw.ww8", "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4160" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4160" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4160" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "STTBF claims " << nStrings << " entries, but only " << nMaxPossibleStrings << " are possible"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4160" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4161 | nStrings = nMaxPossibleStrings; | ||||||
4162 | } | ||||||
4163 | |||||||
4164 | if (nExtraLen && nStrings) | ||||||
4165 | { | ||||||
4166 | const size_t nMaxExtraLen = (rStrm.remainingSize() - (nStrings * nMinStringLen)) / nStrings; | ||||||
4167 | if (nExtraLen > nMaxExtraLen) | ||||||
4168 | { | ||||||
4169 | SAL_WARN("sw.ww8", "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4169" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4169" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4169" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "STTBF claims " << nMaxExtraLen << " extra len, but only " << nMaxExtraLen << " are possible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4169" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4170 | nExtraLen = nMaxExtraLen; | ||||||
4171 | } | ||||||
4172 | } | ||||||
4173 | |||||||
4174 | for (sal_uInt16 i=0; i < nStrings; ++i) | ||||||
4175 | { | ||||||
4176 | if (bUnicode) | ||||||
4177 | rArray.push_back(read_uInt16_PascalString(rStrm)); | ||||||
4178 | else | ||||||
4179 | { | ||||||
4180 | OString aTmp = read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm); | ||||||
4181 | rArray.push_back(OStringToOUString(aTmp, eCS)); | ||||||
4182 | } | ||||||
4183 | |||||||
4184 | // Skip the extra data | ||||||
4185 | if (nExtraLen) | ||||||
4186 | { | ||||||
4187 | if (pExtraArray) | ||||||
4188 | { | ||||||
4189 | ww::bytes extraData(nExtraLen); | ||||||
4190 | rStrm.ReadBytes(extraData.data(), nExtraLen); | ||||||
4191 | pExtraArray->push_back(extraData); | ||||||
4192 | } | ||||||
4193 | else | ||||||
4194 | rStrm.SeekRel( nExtraLen ); | ||||||
4195 | } | ||||||
4196 | } | ||||||
4197 | // read the value of the document variables, if requested. | ||||||
4198 | if (pValueArray) | ||||||
4199 | { | ||||||
4200 | for (sal_uInt16 i=0; i < nStrings; ++i) | ||||||
4201 | { | ||||||
4202 | if( bUnicode ) | ||||||
4203 | pValueArray->push_back(read_uInt16_PascalString(rStrm)); | ||||||
4204 | else | ||||||
4205 | { | ||||||
4206 | OString aTmp = read_uInt8_lenPrefixed_uInt8s_ToOString(rStrm); | ||||||
4207 | pValueArray->push_back(OStringToOUString(aTmp, eCS)); | ||||||
4208 | } | ||||||
4209 | } | ||||||
4210 | } | ||||||
4211 | } | ||||||
4212 | else | ||||||
4213 | { | ||||||
4214 | if( nLen2 != nLen ) | ||||||
4215 | { | ||||||
4216 | OSL_ENSURE(nLen2 == nLen,do { if (true && (!(nLen2 == nLen))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4217" ": "), "%s", "Fib length and read length are different" ); } } while (false) | ||||||
4217 | "Fib length and read length are different")do { if (true && (!(nLen2 == nLen))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4217" ": "), "%s", "Fib length and read length are different" ); } } while (false); | ||||||
4218 | if (nLen > SAL_MAX_UINT16((sal_uInt16) 0xFFFF)) | ||||||
4219 | nLen = SAL_MAX_UINT16((sal_uInt16) 0xFFFF); | ||||||
4220 | else if (nLen < 2 ) | ||||||
4221 | nLen = 2; | ||||||
4222 | nLen2 = static_cast<sal_uInt16>(nLen); | ||||||
4223 | } | ||||||
4224 | sal_uLong nRead = 0; | ||||||
4225 | for( nLen2 -= 2; nRead < nLen2; ) | ||||||
4226 | { | ||||||
4227 | sal_uInt8 nBChar(0); | ||||||
4228 | rStrm.ReadUChar( nBChar ); | ||||||
4229 | ++nRead; | ||||||
4230 | if (nBChar) | ||||||
4231 | { | ||||||
4232 | OString aTmp = read_uInt8s_ToOString(rStrm, nBChar); | ||||||
4233 | nRead += aTmp.getLength(); | ||||||
4234 | rArray.push_back(OStringToOUString(aTmp, eCS)); | ||||||
4235 | } | ||||||
4236 | else | ||||||
4237 | rArray.emplace_back(); | ||||||
4238 | |||||||
4239 | // Skip the extra data (for bVer67 versions this must come from | ||||||
4240 | // external knowledge) | ||||||
4241 | if (nExtraLen) | ||||||
4242 | { | ||||||
4243 | if (pExtraArray) | ||||||
4244 | { | ||||||
4245 | ww::bytes extraData(nExtraLen); | ||||||
4246 | rStrm.ReadBytes(extraData.data(), nExtraLen); | ||||||
4247 | pExtraArray->push_back(extraData); | ||||||
4248 | } | ||||||
4249 | else | ||||||
4250 | rStrm.SeekRel( nExtraLen ); | ||||||
4251 | nRead+=nExtraLen; | ||||||
4252 | } | ||||||
4253 | } | ||||||
4254 | } | ||||||
4255 | } | ||||||
4256 | rStrm.Seek(nOldPos); | ||||||
4257 | } | ||||||
4258 | |||||||
4259 | WW8PLCFx_Book::WW8PLCFx_Book(SvStream* pTableSt, const WW8Fib& rFib) | ||||||
4260 | : WW8PLCFx(rFib, false), nIsEnd(0), nBookmarkId(1) | ||||||
4261 | { | ||||||
4262 | if( !rFib.m_fcPlcfbkf || !rFib.m_lcbPlcfbkf || !rFib.m_fcPlcfbkl || | ||||||
4263 | !rFib.m_lcbPlcfbkl || !rFib.m_fcSttbfbkmk || !rFib.m_lcbSttbfbkmk ) | ||||||
4264 | { | ||||||
4265 | nIMax = 0; | ||||||
4266 | } | ||||||
4267 | else | ||||||
4268 | { | ||||||
4269 | pBook[0].reset( new WW8PLCFspecial(pTableSt,rFib.m_fcPlcfbkf,rFib.m_lcbPlcfbkf,4) ); | ||||||
4270 | |||||||
4271 | pBook[1].reset( new WW8PLCFspecial(pTableSt,rFib.m_fcPlcfbkl,rFib.m_lcbPlcfbkl,0) ); | ||||||
4272 | |||||||
4273 | rtl_TextEncoding eStructChrSet = WW8Fib::GetFIBCharset(rFib.m_chseTables, rFib.m_lid); | ||||||
4274 | |||||||
4275 | WW8ReadSTTBF( (7 < rFib.m_nVersion), *pTableSt, rFib.m_fcSttbfbkmk, | ||||||
4276 | rFib.m_lcbSttbfbkmk, 0, eStructChrSet, aBookNames ); | ||||||
4277 | |||||||
4278 | nIMax = aBookNames.size(); | ||||||
4279 | |||||||
4280 | if( pBook[0]->GetIMax() < nIMax ) // Count of Bookmarks | ||||||
4281 | nIMax = pBook[0]->GetIMax(); | ||||||
4282 | if( pBook[1]->GetIMax() < nIMax ) | ||||||
4283 | nIMax = pBook[1]->GetIMax(); | ||||||
4284 | aStatus.resize(nIMax); | ||||||
4285 | } | ||||||
4286 | } | ||||||
4287 | |||||||
4288 | WW8PLCFx_Book::~WW8PLCFx_Book() | ||||||
4289 | { | ||||||
4290 | } | ||||||
4291 | |||||||
4292 | sal_uInt32 WW8PLCFx_Book::GetIdx() const | ||||||
4293 | { | ||||||
4294 | return nIMax ? pBook[0]->GetIdx() : 0; | ||||||
4295 | } | ||||||
4296 | |||||||
4297 | void WW8PLCFx_Book::SetIdx(sal_uInt32 nI) | ||||||
4298 | { | ||||||
4299 | if( nIMax ) | ||||||
4300 | pBook[0]->SetIdx( nI ); | ||||||
4301 | } | ||||||
4302 | |||||||
4303 | sal_uInt32 WW8PLCFx_Book::GetIdx2() const | ||||||
4304 | { | ||||||
4305 | return nIMax ? ( pBook[1]->GetIdx() | ( nIsEnd ? 0x80000000 : 0 ) ) : 0; | ||||||
4306 | } | ||||||
4307 | |||||||
4308 | void WW8PLCFx_Book::SetIdx2(sal_uInt32 nI) | ||||||
4309 | { | ||||||
4310 | if( nIMax ) | ||||||
4311 | { | ||||||
4312 | pBook[1]->SetIdx( nI & 0x7fffffff ); | ||||||
4313 | nIsEnd = static_cast<sal_uInt16>( ( nI >> 31 ) & 1 ); // 0 or 1 | ||||||
4314 | } | ||||||
4315 | } | ||||||
4316 | |||||||
4317 | bool WW8PLCFx_Book::SeekPos(WW8_CP nCpPos) | ||||||
4318 | { | ||||||
4319 | if( !pBook[0] ) | ||||||
4320 | return false; | ||||||
4321 | |||||||
4322 | bool bOk = pBook[0]->SeekPosExact( nCpPos ); | ||||||
4323 | bOk &= pBook[1]->SeekPosExact( nCpPos ); | ||||||
4324 | nIsEnd = 0; | ||||||
4325 | |||||||
4326 | return bOk; | ||||||
4327 | } | ||||||
4328 | |||||||
4329 | WW8_CP WW8PLCFx_Book::Where() | ||||||
4330 | { | ||||||
4331 | return pBook[nIsEnd]->Where(); | ||||||
4332 | } | ||||||
4333 | |||||||
4334 | long WW8PLCFx_Book::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) | ||||||
4335 | { | ||||||
4336 | void* pData; | ||||||
4337 | rEnd = WW8_CP_MAX; | ||||||
4338 | rLen = 0; | ||||||
4339 | |||||||
4340 | if (!pBook[0] || !pBook[1] || !nIMax || (pBook[nIsEnd]->GetIdx()) >= nIMax) | ||||||
4341 | { | ||||||
4342 | rStart = rEnd = WW8_CP_MAX; | ||||||
4343 | return -1; | ||||||
4344 | } | ||||||
4345 | |||||||
4346 | (void)pBook[nIsEnd]->Get( rStart, pData ); // query position | ||||||
4347 | return pBook[nIsEnd]->GetIdx(); | ||||||
4348 | } | ||||||
4349 | |||||||
4350 | // The operator ++ has a pitfall: If 2 bookmarks adjoin each other, | ||||||
4351 | // we should first go to the end of the first one | ||||||
4352 | // and then to the beginning of the second one. | ||||||
4353 | // But if 2 bookmarks with the length of 0 lie on top of each other, | ||||||
4354 | // we *must* first find the start and end of each bookmark. | ||||||
4355 | // The case of: ][ | ||||||
4356 | // [...] | ||||||
4357 | // ][ | ||||||
4358 | // is not solved yet. | ||||||
4359 | // Because I must jump back and forth in the start- and end-indices then. | ||||||
4360 | // This would require one more index or bitfield to remember | ||||||
4361 | // the already processed bookmarks. | ||||||
4362 | |||||||
4363 | void WW8PLCFx_Book::advance() | ||||||
4364 | { | ||||||
4365 | if( !(pBook[0] && pBook[1] && nIMax) ) | ||||||
4366 | return; | ||||||
4367 | |||||||
4368 | (*pBook[nIsEnd]).advance(); | ||||||
4369 | |||||||
4370 | sal_uLong l0 = pBook[0]->Where(); | ||||||
4371 | sal_uLong l1 = pBook[1]->Where(); | ||||||
4372 | if( l0 < l1 ) | ||||||
4373 | nIsEnd = 0; | ||||||
4374 | else if( l1 < l0 ) | ||||||
4375 | nIsEnd = 1; | ||||||
4376 | else | ||||||
4377 | { | ||||||
4378 | const void * p = pBook[0]->GetData(pBook[0]->GetIdx()); | ||||||
4379 | long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p)); | ||||||
4380 | if (nPairFor == pBook[1]->GetIdx()) | ||||||
4381 | nIsEnd = 0; | ||||||
4382 | else | ||||||
4383 | nIsEnd = nIsEnd ? 0 : 1; | ||||||
4384 | } | ||||||
4385 | } | ||||||
4386 | |||||||
4387 | long WW8PLCFx_Book::GetLen() const | ||||||
4388 | { | ||||||
4389 | if( nIsEnd ) | ||||||
4390 | { | ||||||
4391 | OSL_ENSURE( false, "Incorrect call (1) of PLCF_Book::GetLen()" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4391" ": "), "%s", "Incorrect call (1) of PLCF_Book::GetLen()" ); } } while (false); | ||||||
4392 | return 0; | ||||||
4393 | } | ||||||
4394 | void * p; | ||||||
4395 | WW8_CP nStartPos; | ||||||
4396 | if( !pBook[0]->Get( nStartPos, p ) ) | ||||||
4397 | { | ||||||
4398 | OSL_ENSURE( false, "Incorrect call (2) of PLCF_Book::GetLen()" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4398" ": "), "%s", "Incorrect call (2) of PLCF_Book::GetLen()" ); } } while (false); | ||||||
4399 | return 0; | ||||||
4400 | } | ||||||
4401 | const sal_uInt16 nEndIdx = SVBT16ToUInt16( *static_cast<SVBT16*>(p) ); | ||||||
4402 | long nNum = pBook[1]->GetPos( nEndIdx ); | ||||||
4403 | nNum -= nStartPos; | ||||||
4404 | return nNum; | ||||||
4405 | } | ||||||
4406 | |||||||
4407 | void WW8PLCFx_Book::SetStatus(sal_uInt16 nIndex, eBookStatus eStat) | ||||||
4408 | { | ||||||
4409 | SAL_WARN_IF(nIndex >= nIMax, "sw.ww8",do { if (true && (nIndex >= nIMax)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "bookmark index " << nIndex << " invalid") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "bookmark index " << nIndex << " invalid"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "bookmark index " << nIndex << " invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "bookmark index " << nIndex << " invalid" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "bookmark index " << nIndex << " invalid"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "bookmark index " << nIndex << " invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
4410 | "bookmark index " << nIndex << " invalid")do { if (true && (nIndex >= nIMax)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "bookmark index " << nIndex << " invalid") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "bookmark index " << nIndex << " invalid"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "bookmark index " << nIndex << " invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "bookmark index " << nIndex << " invalid" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "bookmark index " << nIndex << " invalid"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "bookmark index " << nIndex << " invalid"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4410" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4411 | eBookStatus eStatus = aStatus.at(nIndex); | ||||||
4412 | aStatus[nIndex] = static_cast<eBookStatus>(eStatus | eStat); | ||||||
4413 | } | ||||||
4414 | |||||||
4415 | eBookStatus WW8PLCFx_Book::GetStatus() const | ||||||
4416 | { | ||||||
4417 | if (aStatus.empty()) | ||||||
4418 | return BOOK_NORMAL; | ||||||
4419 | long nEndIdx = GetHandle(); | ||||||
4420 | return ( nEndIdx < nIMax ) ? aStatus[nEndIdx] : BOOK_NORMAL; | ||||||
4421 | } | ||||||
4422 | |||||||
4423 | long WW8PLCFx_Book::GetHandle() const | ||||||
4424 | { | ||||||
4425 | if( !pBook[0] || !pBook[1] ) | ||||||
4426 | return LONG_MAX9223372036854775807L; | ||||||
4427 | |||||||
4428 | if( nIsEnd ) | ||||||
4429 | return pBook[1]->GetIdx(); | ||||||
4430 | else | ||||||
4431 | { | ||||||
4432 | if (const void* p = pBook[0]->GetData(pBook[0]->GetIdx())) | ||||||
4433 | return SVBT16ToUInt16( *static_cast<SVBT16 const *>(p) ); | ||||||
4434 | else | ||||||
4435 | return LONG_MAX9223372036854775807L; | ||||||
4436 | } | ||||||
4437 | } | ||||||
4438 | |||||||
4439 | OUString WW8PLCFx_Book::GetBookmark(long nStart,long nEnd, sal_uInt16 &nIndex) | ||||||
4440 | { | ||||||
4441 | bool bFound = false; | ||||||
4442 | sal_uInt16 i = 0; | ||||||
4443 | if (pBook[0] && pBook[1]) | ||||||
4444 | { | ||||||
4445 | WW8_CP nStartCurrent, nEndCurrent; | ||||||
4446 | while (sal::static_int_cast<decltype(aBookNames)::size_type>(i) < aBookNames.size()) | ||||||
4447 | { | ||||||
4448 | void* p; | ||||||
4449 | sal_uInt16 nEndIdx; | ||||||
4450 | |||||||
4451 | if( pBook[0]->GetData( i, nStartCurrent, p ) && p ) | ||||||
4452 | nEndIdx = SVBT16ToUInt16( *static_cast<SVBT16*>(p) ); | ||||||
4453 | else | ||||||
4454 | { | ||||||
4455 | OSL_ENSURE( false, "Bookmark-EndIdx not readable" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4455" ": "), "%s", "Bookmark-EndIdx not readable"); } } while (false); | ||||||
4456 | nEndIdx = i; | ||||||
4457 | } | ||||||
4458 | |||||||
4459 | nEndCurrent = pBook[1]->GetPos( nEndIdx ); | ||||||
4460 | |||||||
4461 | if ((nStartCurrent >= nStart) && (nEndCurrent <= nEnd)) | ||||||
4462 | { | ||||||
4463 | nIndex = i; | ||||||
4464 | bFound=true; | ||||||
4465 | break; | ||||||
4466 | } | ||||||
4467 | ++i; | ||||||
4468 | } | ||||||
4469 | } | ||||||
4470 | return bFound ? aBookNames[i] : OUString(); | ||||||
4471 | } | ||||||
4472 | |||||||
4473 | OUString WW8PLCFx_Book::GetUniqueBookmarkName(const OUString &rSuggestedName) | ||||||
4474 | { | ||||||
4475 | OUString aRet(rSuggestedName.isEmpty() ? OUString("Unnamed") : rSuggestedName); | ||||||
4476 | size_t i = 0; | ||||||
4477 | while (i < aBookNames.size()) | ||||||
4478 | { | ||||||
4479 | if (aRet == aBookNames[i]) | ||||||
4480 | { | ||||||
4481 | sal_Int32 len = aRet.getLength(); | ||||||
4482 | sal_Int32 p = len - 1; | ||||||
4483 | while (p > 0 && aRet[p] >= '0' && aRet[p] <= '9') | ||||||
4484 | --p; | ||||||
4485 | aRet = aRet.copy(0, p+1) + OUString::number(nBookmarkId++); | ||||||
4486 | i = 0; // start search from beginning | ||||||
4487 | } | ||||||
4488 | else | ||||||
4489 | ++i; | ||||||
4490 | } | ||||||
4491 | return aRet; | ||||||
4492 | } | ||||||
4493 | |||||||
4494 | void WW8PLCFx_Book::MapName(OUString& rName) | ||||||
4495 | { | ||||||
4496 | if( !pBook[0] || !pBook[1] ) | ||||||
4497 | return; | ||||||
4498 | |||||||
4499 | size_t i = 0; | ||||||
4500 | while (i < aBookNames.size()) | ||||||
4501 | { | ||||||
4502 | if (rName.equalsIgnoreAsciiCase(aBookNames[i])) | ||||||
4503 | { | ||||||
4504 | rName = aBookNames[i]; | ||||||
4505 | break; | ||||||
4506 | } | ||||||
4507 | ++i; | ||||||
4508 | } | ||||||
4509 | } | ||||||
4510 | |||||||
4511 | const OUString* WW8PLCFx_Book::GetName() const | ||||||
4512 | { | ||||||
4513 | const OUString *pRet = nullptr; | ||||||
4514 | if (!nIsEnd && (pBook[0]->GetIdx() < nIMax)) | ||||||
4515 | pRet = &(aBookNames[pBook[0]->GetIdx()]); | ||||||
4516 | return pRet; | ||||||
4517 | } | ||||||
4518 | |||||||
4519 | WW8PLCFx_AtnBook::WW8PLCFx_AtnBook(SvStream* pTableSt, const WW8Fib& rFib) | ||||||
4520 | : WW8PLCFx(rFib, /*bSprm=*/false), | ||||||
4521 | m_bIsEnd(false) | ||||||
4522 | { | ||||||
4523 | if (!rFib.m_fcPlcfAtnbkf || !rFib.m_lcbPlcfAtnbkf || !rFib.m_fcPlcfAtnbkl || !rFib.m_lcbPlcfAtnbkl) | ||||||
4524 | { | ||||||
4525 | nIMax = 0; | ||||||
4526 | } | ||||||
4527 | else | ||||||
4528 | { | ||||||
4529 | m_pBook[0].reset( new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfAtnbkf, rFib.m_lcbPlcfAtnbkf, 4) ); | ||||||
4530 | m_pBook[1].reset( new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfAtnbkl, rFib.m_lcbPlcfAtnbkl, 0) ); | ||||||
4531 | |||||||
4532 | nIMax = m_pBook[0]->GetIMax(); | ||||||
4533 | if (m_pBook[1]->GetIMax() < nIMax) | ||||||
4534 | nIMax = m_pBook[1]->GetIMax(); | ||||||
4535 | } | ||||||
4536 | } | ||||||
4537 | |||||||
4538 | WW8PLCFx_AtnBook::~WW8PLCFx_AtnBook() | ||||||
4539 | { | ||||||
4540 | } | ||||||
4541 | |||||||
4542 | sal_uInt32 WW8PLCFx_AtnBook::GetIdx() const | ||||||
4543 | { | ||||||
4544 | return nIMax ? m_pBook[0]->GetIdx() : 0; | ||||||
4545 | } | ||||||
4546 | |||||||
4547 | void WW8PLCFx_AtnBook::SetIdx(sal_uInt32 nI) | ||||||
4548 | { | ||||||
4549 | if( nIMax ) | ||||||
4550 | m_pBook[0]->SetIdx( nI ); | ||||||
4551 | } | ||||||
4552 | |||||||
4553 | sal_uInt32 WW8PLCFx_AtnBook::GetIdx2() const | ||||||
4554 | { | ||||||
4555 | if (nIMax) | ||||||
4556 | return m_pBook[1]->GetIdx() | ( m_bIsEnd ? 0x80000000 : 0 ); | ||||||
4557 | else | ||||||
4558 | return 0; | ||||||
4559 | } | ||||||
4560 | |||||||
4561 | void WW8PLCFx_AtnBook::SetIdx2(sal_uInt32 nI) | ||||||
4562 | { | ||||||
4563 | if( nIMax ) | ||||||
4564 | { | ||||||
4565 | m_pBook[1]->SetIdx( nI & 0x7fffffff ); | ||||||
4566 | m_bIsEnd = static_cast<bool>(( nI >> 31 ) & 1); | ||||||
4567 | } | ||||||
4568 | } | ||||||
4569 | |||||||
4570 | bool WW8PLCFx_AtnBook::SeekPos(WW8_CP nCpPos) | ||||||
4571 | { | ||||||
4572 | if (!m_pBook[0]) | ||||||
4573 | return false; | ||||||
4574 | |||||||
4575 | bool bOk = m_pBook[0]->SeekPosExact(nCpPos); | ||||||
4576 | bOk &= m_pBook[1]->SeekPosExact(nCpPos); | ||||||
4577 | m_bIsEnd = false; | ||||||
4578 | |||||||
4579 | return bOk; | ||||||
4580 | } | ||||||
4581 | |||||||
4582 | WW8_CP WW8PLCFx_AtnBook::Where() | ||||||
4583 | { | ||||||
4584 | return m_pBook[static_cast<int>(m_bIsEnd)]->Where(); | ||||||
4585 | } | ||||||
4586 | |||||||
4587 | long WW8PLCFx_AtnBook::GetNoSprms( WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen ) | ||||||
4588 | { | ||||||
4589 | void* pData; | ||||||
4590 | rEnd = WW8_CP_MAX; | ||||||
4591 | rLen = 0; | ||||||
4592 | |||||||
4593 | if (!m_pBook[0] || !m_pBook[1] || !nIMax || (m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx()) >= nIMax) | ||||||
4594 | { | ||||||
4595 | rStart = rEnd = WW8_CP_MAX; | ||||||
4596 | return -1; | ||||||
4597 | } | ||||||
4598 | |||||||
4599 | (void)m_pBook[static_cast<int>(m_bIsEnd)]->Get(rStart, pData); | ||||||
4600 | return m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx(); | ||||||
4601 | } | ||||||
4602 | |||||||
4603 | void WW8PLCFx_AtnBook::advance() | ||||||
4604 | { | ||||||
4605 | if( !(m_pBook[0] && m_pBook[1] && nIMax) ) | ||||||
4606 | return; | ||||||
4607 | |||||||
4608 | (*m_pBook[static_cast<int>(m_bIsEnd)]).advance(); | ||||||
4609 | |||||||
4610 | sal_uLong l0 = m_pBook[0]->Where(); | ||||||
4611 | sal_uLong l1 = m_pBook[1]->Where(); | ||||||
4612 | if( l0 < l1 ) | ||||||
4613 | m_bIsEnd = false; | ||||||
4614 | else if( l1 < l0 ) | ||||||
4615 | m_bIsEnd = true; | ||||||
4616 | else | ||||||
4617 | { | ||||||
4618 | const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()); | ||||||
4619 | long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p)); | ||||||
4620 | if (nPairFor == m_pBook[1]->GetIdx()) | ||||||
4621 | m_bIsEnd = false; | ||||||
4622 | else | ||||||
4623 | m_bIsEnd = !m_bIsEnd; | ||||||
4624 | } | ||||||
4625 | } | ||||||
4626 | |||||||
4627 | long WW8PLCFx_AtnBook::getHandle() const | ||||||
4628 | { | ||||||
4629 | if (!m_pBook[0] || !m_pBook[1]) | ||||||
4630 | return LONG_MAX9223372036854775807L; | ||||||
4631 | |||||||
4632 | if (m_bIsEnd) | ||||||
4633 | return m_pBook[1]->GetIdx(); | ||||||
4634 | else | ||||||
4635 | { | ||||||
4636 | if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx())) | ||||||
4637 | return SVBT16ToUInt16(*static_cast<const SVBT16*>(p)); | ||||||
4638 | else | ||||||
4639 | return LONG_MAX9223372036854775807L; | ||||||
4640 | } | ||||||
4641 | } | ||||||
4642 | |||||||
4643 | bool WW8PLCFx_AtnBook::getIsEnd() const | ||||||
4644 | { | ||||||
4645 | return m_bIsEnd; | ||||||
4646 | } | ||||||
4647 | |||||||
4648 | WW8PLCFx_FactoidBook::WW8PLCFx_FactoidBook(SvStream* pTableSt, const WW8Fib& rFib) | ||||||
4649 | : WW8PLCFx(rFib, /*bSprm=*/false), | ||||||
4650 | m_bIsEnd(false) | ||||||
4651 | { | ||||||
4652 | if (!rFib.m_fcPlcfBkfFactoid || !rFib.m_lcbPlcfBkfFactoid || !rFib.m_fcPlcfBklFactoid || !rFib.m_lcbPlcfBklFactoid) | ||||||
4653 | { | ||||||
4654 | m_nIMax = 0; | ||||||
4655 | } | ||||||
4656 | else | ||||||
4657 | { | ||||||
4658 | m_pBook[0].reset(new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfBkfFactoid, rFib.m_lcbPlcfBkfFactoid, 6)); | ||||||
4659 | m_pBook[1].reset(new WW8PLCFspecial(pTableSt, rFib.m_fcPlcfBklFactoid, rFib.m_lcbPlcfBklFactoid, 4)); | ||||||
4660 | |||||||
4661 | m_nIMax = m_pBook[0]->GetIMax(); | ||||||
4662 | if (m_pBook[1]->GetIMax() < m_nIMax) | ||||||
4663 | m_nIMax = m_pBook[1]->GetIMax(); | ||||||
4664 | } | ||||||
4665 | } | ||||||
4666 | |||||||
4667 | WW8PLCFx_FactoidBook::~WW8PLCFx_FactoidBook() | ||||||
4668 | { | ||||||
4669 | } | ||||||
4670 | |||||||
4671 | sal_uInt32 WW8PLCFx_FactoidBook::GetIdx() const | ||||||
4672 | { | ||||||
4673 | return m_nIMax ? m_pBook[0]->GetIdx() : 0; | ||||||
4674 | } | ||||||
4675 | |||||||
4676 | void WW8PLCFx_FactoidBook::SetIdx(sal_uInt32 nI) | ||||||
4677 | { | ||||||
4678 | if (m_nIMax) | ||||||
4679 | m_pBook[0]->SetIdx(nI); | ||||||
4680 | } | ||||||
4681 | |||||||
4682 | sal_uInt32 WW8PLCFx_FactoidBook::GetIdx2() const | ||||||
4683 | { | ||||||
4684 | if (m_nIMax) | ||||||
4685 | return m_pBook[1]->GetIdx() | (m_bIsEnd ? 0x80000000 : 0); | ||||||
4686 | else | ||||||
4687 | return 0; | ||||||
4688 | } | ||||||
4689 | |||||||
4690 | void WW8PLCFx_FactoidBook::SetIdx2(sal_uInt32 nI) | ||||||
4691 | { | ||||||
4692 | if (m_nIMax) | ||||||
4693 | { | ||||||
4694 | m_pBook[1]->SetIdx(nI & 0x7fffffff); | ||||||
4695 | m_bIsEnd = static_cast<bool>((nI >> 31) & 1); | ||||||
4696 | } | ||||||
4697 | } | ||||||
4698 | |||||||
4699 | bool WW8PLCFx_FactoidBook::SeekPos(WW8_CP nCpPos) | ||||||
4700 | { | ||||||
4701 | if (!m_pBook[0]) | ||||||
4702 | return false; | ||||||
4703 | |||||||
4704 | bool bOk = m_pBook[0]->SeekPosExact(nCpPos); | ||||||
4705 | bOk &= m_pBook[1]->SeekPosExact(nCpPos); | ||||||
4706 | m_bIsEnd = false; | ||||||
4707 | |||||||
4708 | return bOk; | ||||||
4709 | } | ||||||
4710 | |||||||
4711 | WW8_CP WW8PLCFx_FactoidBook::Where() | ||||||
4712 | { | ||||||
4713 | return m_pBook[static_cast<int>(m_bIsEnd)]->Where(); | ||||||
4714 | } | ||||||
4715 | |||||||
4716 | long WW8PLCFx_FactoidBook::GetNoSprms(WW8_CP& rStart, WW8_CP& rEnd, sal_Int32& rLen) | ||||||
4717 | { | ||||||
4718 | void* pData; | ||||||
4719 | rEnd = WW8_CP_MAX; | ||||||
4720 | rLen = 0; | ||||||
4721 | |||||||
4722 | if (!m_pBook[0] || !m_pBook[1] || !m_nIMax || (m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx()) >= m_nIMax) | ||||||
4723 | { | ||||||
4724 | rStart = rEnd = WW8_CP_MAX; | ||||||
4725 | return -1; | ||||||
4726 | } | ||||||
4727 | |||||||
4728 | (void)m_pBook[static_cast<int>(m_bIsEnd)]->Get(rStart, pData); | ||||||
4729 | return m_pBook[static_cast<int>(m_bIsEnd)]->GetIdx(); | ||||||
4730 | } | ||||||
4731 | |||||||
4732 | void WW8PLCFx_FactoidBook::advance() | ||||||
4733 | { | ||||||
4734 | if (!(m_pBook[0] && m_pBook[1] && m_nIMax)) | ||||||
4735 | return; | ||||||
4736 | |||||||
4737 | (*m_pBook[static_cast<int>(m_bIsEnd)]).advance(); | ||||||
4738 | |||||||
4739 | sal_uLong l0 = m_pBook[0]->Where(); | ||||||
4740 | sal_uLong l1 = m_pBook[1]->Where(); | ||||||
4741 | if (l0 < l1) | ||||||
4742 | m_bIsEnd = false; | ||||||
4743 | else if (l1 < l0) | ||||||
4744 | m_bIsEnd = true; | ||||||
4745 | else | ||||||
4746 | { | ||||||
4747 | const void * p = m_pBook[0]->GetData(m_pBook[0]->GetIdx()); | ||||||
4748 | long nPairFor = (p == nullptr) ? 0 : SVBT16ToUInt16(*static_cast<SVBT16 const *>(p)); | ||||||
4749 | if (nPairFor == m_pBook[1]->GetIdx()) | ||||||
4750 | m_bIsEnd = false; | ||||||
4751 | else | ||||||
4752 | m_bIsEnd = !m_bIsEnd; | ||||||
4753 | } | ||||||
4754 | } | ||||||
4755 | |||||||
4756 | long WW8PLCFx_FactoidBook::getHandle() const | ||||||
4757 | { | ||||||
4758 | if (!m_pBook[0] || !m_pBook[1]) | ||||||
4759 | return LONG_MAX9223372036854775807L; | ||||||
4760 | |||||||
4761 | if (m_bIsEnd) | ||||||
4762 | return m_pBook[1]->GetIdx(); | ||||||
4763 | else | ||||||
4764 | { | ||||||
4765 | if (const void* p = m_pBook[0]->GetData(m_pBook[0]->GetIdx())) | ||||||
4766 | return SVBT16ToUInt16(*static_cast<const SVBT16*>(p)); | ||||||
4767 | else | ||||||
4768 | return LONG_MAX9223372036854775807L; | ||||||
4769 | } | ||||||
4770 | } | ||||||
4771 | |||||||
4772 | bool WW8PLCFx_FactoidBook::getIsEnd() const | ||||||
4773 | { | ||||||
4774 | return m_bIsEnd; | ||||||
4775 | } | ||||||
4776 | |||||||
4777 | // In the end of a paragraph in WW6 the attribute extends after the <CR>. | ||||||
4778 | // This will be reset by one character to be used with SW, | ||||||
4779 | // if we don't expect trouble thereby. | ||||||
4780 | void WW8PLCFMan::AdjustEnds( WW8PLCFxDesc& rDesc ) | ||||||
4781 | { | ||||||
4782 | // might be necessary to do this for pChp and/or pSep as well, | ||||||
4783 | // but its definitely the case for paragraphs that EndPos > StartPos | ||||||
4784 | // for a well formed paragraph as those always have a paragraph | ||||||
4785 | // <cr> in them | ||||||
4786 | if (&rDesc == m_pPap && rDesc.bRealLineEnd) | ||||||
4787 | { | ||||||
4788 | if (rDesc.nStartPos == rDesc.nEndPos && rDesc.nEndPos != WW8_CP_MAX) | ||||||
4789 | { | ||||||
4790 | SAL_WARN("sw.ww8", "WW8PLCFxDesc End same as Start, abandoning to avoid looping")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4790" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4790" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4790" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "WW8PLCFxDesc End same as Start, abandoning to avoid looping" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4790" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4791 | rDesc.nEndPos = WW8_CP_MAX; | ||||||
4792 | } | ||||||
4793 | } | ||||||
4794 | |||||||
4795 | //Store old end position for supercool new property finder that uses | ||||||
4796 | //cp instead of fc's as nature intended | ||||||
4797 | rDesc.nOrigEndPos = rDesc.nEndPos; | ||||||
4798 | rDesc.nOrigStartPos = rDesc.nStartPos; | ||||||
4799 | |||||||
4800 | /* | ||||||
4801 | Normally given ^XXX{para end}^ we don't actually insert a para end | ||||||
4802 | character into the document, so we clip the para end property one to the | ||||||
4803 | left to make the para properties end when the paragraph text does. In a | ||||||
4804 | drawing textbox we actually do insert a para end character, so we don't | ||||||
4805 | clip it. Making the para end properties end after the para end char. | ||||||
4806 | */ | ||||||
4807 | if (GetDoingDrawTextBox()) | ||||||
4808 | return; | ||||||
4809 | |||||||
4810 | if ( (&rDesc == m_pPap) && rDesc.bRealLineEnd ) | ||||||
4811 | { | ||||||
4812 | if ( m_pPap->nEndPos != WW8_CP_MAX ) // Para adjust | ||||||
4813 | { | ||||||
4814 | m_nLineEnd = m_pPap->nEndPos;// nLineEnd points *after* the <CR> | ||||||
4815 | m_pPap->nEndPos--; // shorten paragraph end by one character | ||||||
4816 | |||||||
4817 | // Is there already a sep end, which points to the current paragraph end? | ||||||
4818 | // Then we also must shorten by one character | ||||||
4819 | if( m_pSep->nEndPos == m_nLineEnd ) | ||||||
4820 | m_pSep->nEndPos--; | ||||||
4821 | } | ||||||
4822 | } | ||||||
4823 | else if (&rDesc == m_pSep) | ||||||
4824 | { | ||||||
4825 | // Sep Adjust if end Char-Attr == paragraph end ... | ||||||
4826 | if( (rDesc.nEndPos == m_nLineEnd) && (rDesc.nEndPos > rDesc.nStartPos) ) | ||||||
4827 | rDesc.nEndPos--; // ... then shorten by one character | ||||||
4828 | } | ||||||
4829 | } | ||||||
4830 | |||||||
4831 | void WW8PLCFxDesc::ReduceByOffset() | ||||||
4832 | { | ||||||
4833 | SAL_WARN_IF(WW8_CP_MAX != nStartPos && nStartPos > nEndPos, "sw.ww8",do { if (true && (WW8_CP_MAX != nStartPos && nStartPos > nEndPos)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << nEndPos << " before Start " << nStartPos) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEndPos << " before Start " << nStartPos), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEndPos << " before Start " << nStartPos; ::sal::detail::log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << nEndPos << " before Start " << nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEndPos << " before Start " << nStartPos), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEndPos << " before Start " << nStartPos; ::sal::detail::log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
4834 | "End " << nEndPos << " before Start " << nStartPos)do { if (true && (WW8_CP_MAX != nStartPos && nStartPos > nEndPos)) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << nEndPos << " before Start " << nStartPos) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEndPos << " before Start " << nStartPos), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEndPos << " before Start " << nStartPos; ::sal::detail::log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << nEndPos << " before Start " << nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEndPos << " before Start " << nStartPos), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEndPos << " before Start " << nStartPos; ::sal::detail::log( (:: SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4834" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4835 | |||||||
4836 | if( nStartPos != WW8_CP_MAX ) | ||||||
4837 | { | ||||||
4838 | /* | ||||||
4839 | ##516##,##517## | ||||||
4840 | Force the property change to happen at the beginning of this | ||||||
4841 | subdocument, same as in GetNewNoSprms, except that the target type is | ||||||
4842 | attributes attached to a piece that might span subdocument boundaries | ||||||
4843 | */ | ||||||
4844 | if (nCpOfs > nStartPos) | ||||||
4845 | nStartPos = 0; | ||||||
4846 | else | ||||||
4847 | nStartPos -= nCpOfs; | ||||||
4848 | } | ||||||
4849 | if (nEndPos != WW8_CP_MAX) | ||||||
4850 | { | ||||||
4851 | if (nCpOfs > nEndPos) | ||||||
4852 | { | ||||||
4853 | SAL_WARN("sw.ww8", "broken subdocument piece entry")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken subdocument piece entry" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4853" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken subdocument piece entry"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken subdocument piece entry"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4853" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken subdocument piece entry") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4853" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken subdocument piece entry"), 0 ); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken subdocument piece entry"; ::sal::detail::log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4853" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4854 | nEndPos = WW8_CP_MAX; | ||||||
4855 | } | ||||||
4856 | else | ||||||
4857 | nEndPos -= nCpOfs; | ||||||
4858 | } | ||||||
4859 | } | ||||||
4860 | |||||||
4861 | void WW8PLCFMan::GetNewSprms( WW8PLCFxDesc& rDesc ) | ||||||
4862 | { | ||||||
4863 | rDesc.pPLCFx->GetSprms(&rDesc); | ||||||
4864 | rDesc.ReduceByOffset(); | ||||||
4865 | |||||||
4866 | rDesc.bFirstSprm = true; | ||||||
4867 | AdjustEnds( rDesc ); | ||||||
4868 | rDesc.nOrigSprmsLen = rDesc.nSprmsLen; | ||||||
4869 | } | ||||||
4870 | |||||||
4871 | void WW8PLCFMan::GetNewNoSprms( WW8PLCFxDesc& rDesc ) | ||||||
4872 | { | ||||||
4873 | rDesc.nCp2OrIdx = rDesc.pPLCFx->GetNoSprms(rDesc.nStartPos, rDesc.nEndPos, | ||||||
4874 | rDesc.nSprmsLen); | ||||||
4875 | |||||||
4876 | SAL_WARN_IF(WW8_CP_MAX != rDesc.nStartPos && rDesc.nStartPos > rDesc.nEndPos, "sw.ww8",do { if (true && (WW8_CP_MAX != rDesc.nStartPos && rDesc.nStartPos > rDesc.nEndPos)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
4877 | "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos)do { if (true && (WW8_CP_MAX != rDesc.nStartPos && rDesc.nStartPos > rDesc.nEndPos)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << rDesc.nEndPos << " before Start " << rDesc.nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "4877" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
4878 | |||||||
4879 | rDesc.ReduceByOffset(); | ||||||
4880 | |||||||
4881 | rDesc.bFirstSprm = true; | ||||||
4882 | rDesc.nOrigSprmsLen = rDesc.nSprmsLen; | ||||||
4883 | } | ||||||
4884 | |||||||
4885 | sal_uInt16 WW8PLCFMan::GetId(const WW8PLCFxDesc* p) const | ||||||
4886 | { | ||||||
4887 | sal_uInt16 nId = 0; // Id = 0 for empty attributes | ||||||
4888 | |||||||
4889 | if (p == m_pField) | ||||||
4890 | nId = eFLD; | ||||||
4891 | else if (p == m_pFootnote) | ||||||
4892 | nId = eFTN; | ||||||
4893 | else if (p == m_pEdn) | ||||||
4894 | nId = eEDN; | ||||||
4895 | else if (p == m_pAnd) | ||||||
4896 | nId = eAND; | ||||||
4897 | else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) | ||||||
4898 | nId = maSprmParser.GetSprmId(p->pMemPos); | ||||||
4899 | |||||||
4900 | return nId; | ||||||
4901 | } | ||||||
4902 | |||||||
4903 | WW8PLCFMan::WW8PLCFMan(const WW8ScannerBase* pBase, ManTypes nType, long nStartCp, | ||||||
4904 | bool bDoingDrawTextBox) | ||||||
4905 | : maSprmParser(*pBase->m_pWw8Fib), | ||||||
4906 | m_nLineEnd(WW8_CP_MAX), | ||||||
4907 | mbDoingDrawTextBox(bDoingDrawTextBox) | ||||||
4908 | { | ||||||
4909 | m_pWwFib = pBase->m_pWw8Fib; | ||||||
4910 | |||||||
4911 | m_nManType = nType; | ||||||
4912 | |||||||
4913 | if( MAN_MAINTEXT == nType ) | ||||||
4914 | { | ||||||
4915 | // search order of the attributes | ||||||
4916 | m_nPLCF = MAN_PLCF_COUNT; | ||||||
4917 | m_pField = &m_aD[0]; | ||||||
4918 | m_pBkm = &m_aD[1]; | ||||||
4919 | m_pEdn = &m_aD[2]; | ||||||
4920 | m_pFootnote = &m_aD[3]; | ||||||
4921 | m_pAnd = &m_aD[4]; | ||||||
4922 | |||||||
4923 | m_pPcd = pBase->m_pPLCFx_PCD ? &m_aD[5] : nullptr; | ||||||
4924 | //pPcdA index == pPcd index + 1 | ||||||
4925 | m_pPcdA = pBase->m_pPLCFx_PCDAttrs ? &m_aD[6] : nullptr; | ||||||
4926 | |||||||
4927 | m_pChp = &m_aD[7]; | ||||||
4928 | m_pPap = &m_aD[8]; | ||||||
4929 | m_pSep = &m_aD[9]; | ||||||
4930 | m_pAtnBkm = &m_aD[10]; | ||||||
4931 | m_pFactoidBkm = &m_aD[11]; | ||||||
4932 | |||||||
4933 | m_pSep->pPLCFx = pBase->m_pSepPLCF.get(); | ||||||
4934 | m_pFootnote->pPLCFx = pBase->m_pFootnotePLCF.get(); | ||||||
4935 | m_pEdn->pPLCFx = pBase->m_pEdnPLCF.get(); | ||||||
4936 | m_pBkm->pPLCFx = pBase->m_pBook.get(); | ||||||
4937 | m_pAnd->pPLCFx = pBase->m_pAndPLCF.get(); | ||||||
4938 | m_pAtnBkm->pPLCFx = pBase->m_pAtnBook.get(); | ||||||
4939 | m_pFactoidBkm->pPLCFx = pBase->m_pFactoidBook.get(); | ||||||
4940 | |||||||
4941 | } | ||||||
4942 | else | ||||||
4943 | { | ||||||
4944 | // search order of the attributes | ||||||
4945 | m_nPLCF = 7; | ||||||
4946 | m_pField = &m_aD[0]; | ||||||
4947 | m_pBkm = pBase->m_pBook ? &m_aD[1] : nullptr; | ||||||
4948 | |||||||
4949 | m_pPcd = pBase->m_pPLCFx_PCD ? &m_aD[2] : nullptr; | ||||||
4950 | //pPcdA index == pPcd index + 1 | ||||||
4951 | m_pPcdA= pBase->m_pPLCFx_PCDAttrs ? &m_aD[3] : nullptr; | ||||||
4952 | |||||||
4953 | m_pChp = &m_aD[4]; | ||||||
4954 | m_pPap = &m_aD[5]; | ||||||
4955 | m_pSep = &m_aD[6]; // Dummy | ||||||
4956 | |||||||
4957 | m_pAnd = m_pAtnBkm = m_pFactoidBkm = m_pFootnote = m_pEdn = nullptr; // not used at SpezText | ||||||
4958 | } | ||||||
4959 | |||||||
4960 | m_pChp->pPLCFx = pBase->m_pChpPLCF.get(); | ||||||
4961 | m_pPap->pPLCFx = pBase->m_pPapPLCF.get(); | ||||||
4962 | if( m_pPcd ) | ||||||
4963 | m_pPcd->pPLCFx = pBase->m_pPLCFx_PCD.get(); | ||||||
4964 | if( m_pPcdA ) | ||||||
4965 | m_pPcdA->pPLCFx= pBase->m_pPLCFx_PCDAttrs.get(); | ||||||
4966 | if( m_pBkm ) | ||||||
4967 | m_pBkm->pPLCFx = pBase->m_pBook.get(); | ||||||
4968 | |||||||
4969 | m_pMagicTables = pBase->m_pMagicTables.get(); | ||||||
4970 | m_pSubdocs = pBase->m_pSubdocs.get(); | ||||||
4971 | m_pExtendedAtrds = pBase->m_pExtendedAtrds.get(); | ||||||
4972 | |||||||
4973 | switch( nType ) // field initialization | ||||||
4974 | { | ||||||
4975 | case MAN_HDFT: | ||||||
4976 | m_pField->pPLCFx = pBase->m_pFieldHdFtPLCF.get(); | ||||||
4977 | m_pFdoa = pBase->m_pHdFtFdoa.get(); | ||||||
4978 | m_pTxbx = pBase->m_pHdFtTxbx.get(); | ||||||
4979 | m_pTxbxBkd = pBase->m_pHdFtTxbxBkd.get(); | ||||||
4980 | break; | ||||||
4981 | case MAN_FTN: | ||||||
4982 | m_pField->pPLCFx = pBase->m_pFieldFootnotePLCF.get(); | ||||||
4983 | m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr; | ||||||
4984 | break; | ||||||
4985 | case MAN_EDN: | ||||||
4986 | m_pField->pPLCFx = pBase->m_pFieldEdnPLCF.get(); | ||||||
4987 | m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr; | ||||||
4988 | break; | ||||||
4989 | case MAN_AND: | ||||||
4990 | m_pField->pPLCFx = pBase->m_pFieldAndPLCF.get(); | ||||||
4991 | m_pFdoa = m_pTxbx = m_pTxbxBkd = nullptr; | ||||||
4992 | break; | ||||||
4993 | case MAN_TXBX: | ||||||
4994 | m_pField->pPLCFx = pBase->m_pFieldTxbxPLCF.get(); | ||||||
4995 | m_pTxbx = pBase->m_pMainTxbx.get(); | ||||||
4996 | m_pTxbxBkd = pBase->m_pMainTxbxBkd.get(); | ||||||
4997 | m_pFdoa = nullptr; | ||||||
4998 | break; | ||||||
4999 | case MAN_TXBX_HDFT: | ||||||
5000 | m_pField->pPLCFx = pBase->m_pFieldTxbxHdFtPLCF.get(); | ||||||
5001 | m_pTxbx = pBase->m_pHdFtTxbx.get(); | ||||||
5002 | m_pTxbxBkd = pBase->m_pHdFtTxbxBkd.get(); | ||||||
5003 | m_pFdoa = nullptr; | ||||||
5004 | break; | ||||||
5005 | default: | ||||||
5006 | m_pField->pPLCFx = pBase->m_pFieldPLCF.get(); | ||||||
5007 | m_pFdoa = pBase->m_pMainFdoa.get(); | ||||||
5008 | m_pTxbx = pBase->m_pMainTxbx.get(); | ||||||
5009 | m_pTxbxBkd = pBase->m_pMainTxbxBkd.get(); | ||||||
5010 | break; | ||||||
5011 | } | ||||||
5012 | |||||||
5013 | WW8_CP cp = 0; | ||||||
5014 | m_pWwFib->GetBaseCp(nType, &cp); //TODO: check return value | ||||||
5015 | m_nCpO = cp; | ||||||
5016 | |||||||
5017 | if( nStartCp || m_nCpO ) | ||||||
5018 | SeekPos( nStartCp ); // adjust PLCFe at text StartPos | ||||||
5019 | |||||||
5020 | // initialization to the member vars Low-Level | ||||||
5021 | GetChpPLCF()->ResetAttrStartEnd(); | ||||||
5022 | GetPapPLCF()->ResetAttrStartEnd(); | ||||||
5023 | for( sal_uInt16 i=0; i < m_nPLCF; ++i) | ||||||
5024 | { | ||||||
5025 | WW8PLCFxDesc* p = &m_aD[i]; | ||||||
5026 | |||||||
5027 | /* | ||||||
5028 | ##516##,##517## | ||||||
5029 | For subdocuments we modify the cp of properties to be relative to | ||||||
5030 | the beginning of subdocuments, we should also do the same for | ||||||
5031 | piecetable changes, and piecetable properties, otherwise a piece | ||||||
5032 | change that happens in a subdocument is lost. | ||||||
5033 | */ | ||||||
5034 | p->nCpOfs = ( p == m_pChp || p == m_pPap || p == m_pBkm || p == m_pPcd || | ||||||
5035 | p == m_pPcdA ) ? m_nCpO : 0; | ||||||
5036 | |||||||
5037 | p->nCp2OrIdx = 0; | ||||||
5038 | p->bFirstSprm = false; | ||||||
5039 | p->pIdStack = nullptr; | ||||||
5040 | |||||||
5041 | if ((p == m_pChp) || (p == m_pPap)) | ||||||
5042 | p->nStartPos = p->nEndPos = nStartCp; | ||||||
5043 | else | ||||||
5044 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
5045 | } | ||||||
5046 | |||||||
5047 | // initialization to the member vars High-Level | ||||||
5048 | for( sal_uInt16 i=0; i<m_nPLCF; ++i){ | ||||||
5049 | WW8PLCFxDesc* p = &m_aD[i]; | ||||||
5050 | |||||||
5051 | if( !p->pPLCFx ) | ||||||
5052 | { | ||||||
5053 | p->nStartPos = p->nEndPos = WW8_CP_MAX; | ||||||
5054 | continue; | ||||||
5055 | } | ||||||
5056 | |||||||
5057 | if( p->pPLCFx->IsSprm() ) | ||||||
5058 | { | ||||||
5059 | // Careful: nEndPos must be | ||||||
5060 | p->pIdStack = new std::stack<sal_uInt16>; | ||||||
5061 | if ((p == m_pChp) || (p == m_pPap)) | ||||||
5062 | { | ||||||
5063 | WW8_CP nTemp = p->nEndPos+p->nCpOfs; | ||||||
5064 | p->pMemPos = nullptr; | ||||||
5065 | p->nSprmsLen = 0; | ||||||
5066 | p->nStartPos = nTemp; | ||||||
5067 | if (!(*p->pPLCFx).SeekPos(p->nStartPos)) | ||||||
5068 | p->nEndPos = p->nStartPos = WW8_CP_MAX; | ||||||
5069 | else | ||||||
5070 | GetNewSprms( *p ); | ||||||
5071 | } | ||||||
5072 | else | ||||||
5073 | GetNewSprms( *p ); // initialized at all PLCFs | ||||||
5074 | } | ||||||
5075 | else if( p->pPLCFx ) | ||||||
5076 | GetNewNoSprms( *p ); | ||||||
5077 | } | ||||||
5078 | } | ||||||
5079 | |||||||
5080 | WW8PLCFMan::~WW8PLCFMan() | ||||||
5081 | { | ||||||
5082 | for( sal_uInt16 i=0; i<m_nPLCF; i++) | ||||||
5083 | delete m_aD[i].pIdStack; | ||||||
5084 | } | ||||||
5085 | |||||||
5086 | // 0. which attr class, | ||||||
5087 | // 1. if it's an attr start, | ||||||
5088 | // 2. CP, where is next attr change | ||||||
5089 | sal_uInt16 WW8PLCFMan::WhereIdx(bool *const pbStart, WW8_CP *const pPos) const | ||||||
5090 | { | ||||||
5091 | OSL_ENSURE(m_nPLCF,"What the hell")do { if (true && (!(m_nPLCF))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5091" ": "), "%s", "What the hell"); } } while (false); | ||||||
5092 | WW8_CP nNext = WW8_CP_MAX; // search order: | ||||||
5093 | sal_uInt16 nNextIdx = m_nPLCF;// first ending found ( CHP, PAP, ( SEP ) ), | ||||||
5094 | bool bStart = true; // now find beginnings ( ( SEP ), PAP, CHP ) | ||||||
5095 | const WW8PLCFxDesc* pD; | ||||||
5096 | for (sal_uInt16 i=0; i < m_nPLCF; ++i) | ||||||
5097 | { | ||||||
5098 | pD = &m_aD[i]; | ||||||
5099 | if (pD != m_pPcdA) | ||||||
5100 | { | ||||||
5101 | if( (pD->nEndPos < nNext) && (pD->nStartPos == WW8_CP_MAX) ) | ||||||
5102 | { | ||||||
5103 | // otherwise start = end | ||||||
5104 | nNext = pD->nEndPos; | ||||||
5105 | nNextIdx = i; | ||||||
5106 | bStart = false; | ||||||
5107 | } | ||||||
5108 | } | ||||||
5109 | } | ||||||
5110 | for (sal_uInt16 i=m_nPLCF; i > 0; --i) | ||||||
5111 | { | ||||||
5112 | pD = &m_aD[i-1]; | ||||||
5113 | if (pD != m_pPcdA && pD->nStartPos < nNext ) | ||||||
5114 | { | ||||||
5115 | nNext = pD->nStartPos; | ||||||
5116 | nNextIdx = i-1; | ||||||
5117 | bStart = true; | ||||||
5118 | } | ||||||
5119 | } | ||||||
5120 | if( pPos ) | ||||||
5121 | *pPos = nNext; | ||||||
5122 | if( pbStart ) | ||||||
5123 | *pbStart = bStart; | ||||||
5124 | return nNextIdx; | ||||||
5125 | } | ||||||
5126 | |||||||
5127 | // gives the CP pos of the next attr change | ||||||
5128 | WW8_CP WW8PLCFMan::Where() const | ||||||
5129 | { | ||||||
5130 | WW8_CP l; | ||||||
5131 | WhereIdx(nullptr, &l); | ||||||
5132 | return l; | ||||||
5133 | } | ||||||
5134 | |||||||
5135 | void WW8PLCFMan::SeekPos( long nNewCp ) | ||||||
5136 | { | ||||||
5137 | m_pChp->pPLCFx->SeekPos( nNewCp + m_nCpO ); // create new attr | ||||||
5138 | m_pPap->pPLCFx->SeekPos( nNewCp + m_nCpO ); | ||||||
5139 | m_pField->pPLCFx->SeekPos( nNewCp ); | ||||||
5140 | if( m_pPcd ) | ||||||
5141 | m_pPcd->pPLCFx->SeekPos( nNewCp + m_nCpO ); | ||||||
5142 | if( m_pBkm ) | ||||||
5143 | m_pBkm->pPLCFx->SeekPos( nNewCp + m_nCpO ); | ||||||
5144 | } | ||||||
5145 | |||||||
5146 | void WW8PLCFMan::SaveAllPLCFx( WW8PLCFxSaveAll& rSave ) const | ||||||
5147 | { | ||||||
5148 | sal_uInt16 n=0; | ||||||
5149 | if( m_pPcd ) | ||||||
5150 | m_pPcd->Save( rSave.aS[n++] ); | ||||||
5151 | if( m_pPcdA ) | ||||||
5152 | m_pPcdA->Save( rSave.aS[n++] ); | ||||||
5153 | |||||||
5154 | for(sal_uInt16 i=0; i<m_nPLCF; ++i) | ||||||
5155 | if( m_pPcd != &m_aD[i] && m_pPcdA != &m_aD[i] ) | ||||||
5156 | m_aD[i].Save( rSave.aS[n++] ); | ||||||
5157 | } | ||||||
5158 | |||||||
5159 | void WW8PLCFMan::RestoreAllPLCFx( const WW8PLCFxSaveAll& rSave ) | ||||||
5160 | { | ||||||
5161 | sal_uInt16 n=0; | ||||||
5162 | if( m_pPcd ) | ||||||
5163 | m_pPcd->Restore( rSave.aS[n++] ); | ||||||
5164 | if( m_pPcdA ) | ||||||
5165 | m_pPcdA->Restore( rSave.aS[n++] ); | ||||||
5166 | |||||||
5167 | for(sal_uInt16 i=0; i<m_nPLCF; ++i) | ||||||
5168 | if( m_pPcd != &m_aD[i] && m_pPcdA != &m_aD[i] ) | ||||||
5169 | m_aD[i].Restore( rSave.aS[n++] ); | ||||||
5170 | } | ||||||
5171 | |||||||
5172 | void WW8PLCFMan::GetSprmStart( short nIdx, WW8PLCFManResult* pRes ) const | ||||||
5173 | { | ||||||
5174 | memset( pRes, 0, sizeof( WW8PLCFManResult ) ); | ||||||
5175 | |||||||
5176 | // verifying !!! | ||||||
5177 | |||||||
5178 | pRes->nMemLen = 0; | ||||||
5179 | |||||||
5180 | const WW8PLCFxDesc* p = &m_aD[nIdx]; | ||||||
5181 | |||||||
5182 | // first Sprm in a Group | ||||||
5183 | if( p->bFirstSprm ) | ||||||
5184 | { | ||||||
5185 | if( p == m_pPap ) | ||||||
5186 | pRes->nFlags |= MAN_MASK_NEW_PAP; | ||||||
5187 | else if( p == m_pSep ) | ||||||
5188 | pRes->nFlags |= MAN_MASK_NEW_SEP; | ||||||
5189 | } | ||||||
5190 | pRes->pMemPos = p->pMemPos; | ||||||
5191 | pRes->nSprmId = GetId(p); | ||||||
5192 | pRes->nCp2OrIdx = p->nCp2OrIdx; | ||||||
5193 | if ((p == m_pFootnote) || (p == m_pEdn) || (p == m_pAnd)) | ||||||
5194 | pRes->nMemLen = p->nSprmsLen; | ||||||
5195 | else if (p->nSprmsLen >= maSprmParser.MinSprmLen()) //normal | ||||||
5196 | { | ||||||
5197 | // Length of actual sprm | ||||||
5198 | pRes->nMemLen = maSprmParser.GetSprmSize(pRes->nSprmId, pRes->pMemPos, p->nSprmsLen); | ||||||
5199 | if (pRes->nMemLen > p->nSprmsLen) | ||||||
5200 | { | ||||||
5201 | SAL_WARN("sw.ww8", "Short sprm, len " << pRes->nMemLen << " claimed, max possible is " << p->nSprmsLen)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Short sprm, len " << pRes->nMemLen << " claimed, max possible is " << p->nSprmsLen) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5201" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Short sprm, len " << pRes-> nMemLen << " claimed, max possible is " << p-> nSprmsLen), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Short sprm, len " << pRes ->nMemLen << " claimed, max possible is " << p ->nSprmsLen; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5201" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Short sprm, len " << pRes->nMemLen << " claimed, max possible is " << p->nSprmsLen) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5201" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "Short sprm, len " << pRes-> nMemLen << " claimed, max possible is " << p-> nSprmsLen), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Short sprm, len " << pRes ->nMemLen << " claimed, max possible is " << p ->nSprmsLen; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5201" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5202 | pRes->nSprmId = 0; | ||||||
5203 | } | ||||||
5204 | } | ||||||
5205 | } | ||||||
5206 | |||||||
5207 | void WW8PLCFMan::GetSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const | ||||||
5208 | { | ||||||
5209 | memset( pRes, 0, sizeof( WW8PLCFManResult ) ); | ||||||
5210 | |||||||
5211 | const WW8PLCFxDesc* p = &m_aD[nIdx]; | ||||||
5212 | |||||||
5213 | if (!(p->pIdStack->empty())) | ||||||
5214 | pRes->nSprmId = p->pIdStack->top(); // get end position | ||||||
5215 | else | ||||||
5216 | { | ||||||
5217 | OSL_ENSURE( false, "No Id on the Stack" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5217" ": "), "%s", "No Id on the Stack"); } } while (false ); | ||||||
5218 | pRes->nSprmId = 0; | ||||||
5219 | } | ||||||
5220 | } | ||||||
5221 | |||||||
5222 | void WW8PLCFMan::GetNoSprmStart( short nIdx, WW8PLCFManResult* pRes ) const | ||||||
5223 | { | ||||||
5224 | const WW8PLCFxDesc* p = &m_aD[nIdx]; | ||||||
5225 | |||||||
5226 | pRes->nCpPos = p->nStartPos; | ||||||
5227 | pRes->nMemLen = p->nSprmsLen; | ||||||
5228 | pRes->nCp2OrIdx = p->nCp2OrIdx; | ||||||
5229 | |||||||
5230 | if( p == m_pField ) | ||||||
5231 | pRes->nSprmId = eFLD; | ||||||
5232 | else if( p == m_pFootnote ) | ||||||
5233 | pRes->nSprmId = eFTN; | ||||||
5234 | else if( p == m_pEdn ) | ||||||
5235 | pRes->nSprmId = eEDN; | ||||||
5236 | else if( p == m_pBkm ) | ||||||
5237 | pRes->nSprmId = eBKN; | ||||||
5238 | else if (p == m_pAtnBkm) | ||||||
5239 | pRes->nSprmId = eATNBKN; | ||||||
5240 | else if (p == m_pFactoidBkm) | ||||||
5241 | pRes->nSprmId = eFACTOIDBKN; | ||||||
5242 | else if( p == m_pAnd ) | ||||||
5243 | pRes->nSprmId = eAND; | ||||||
5244 | else if( p == m_pPcd ) | ||||||
5245 | { | ||||||
5246 | //We slave the piece table attributes to the piece table, the piece | ||||||
5247 | //table attribute iterator contains the sprms for this piece. | ||||||
5248 | GetSprmStart( nIdx+1, pRes ); | ||||||
5249 | } | ||||||
5250 | else | ||||||
5251 | pRes->nSprmId = 0; // default: not found | ||||||
5252 | } | ||||||
5253 | |||||||
5254 | void WW8PLCFMan::GetNoSprmEnd( short nIdx, WW8PLCFManResult* pRes ) const | ||||||
5255 | { | ||||||
5256 | pRes->nMemLen = -1; // end tag | ||||||
5257 | |||||||
5258 | if( &m_aD[nIdx] == m_pBkm ) | ||||||
5259 | pRes->nSprmId = eBKN; | ||||||
5260 | else if (&m_aD[nIdx] == m_pAtnBkm) | ||||||
5261 | pRes->nSprmId = eATNBKN; | ||||||
5262 | else if (&m_aD[nIdx] == m_pFactoidBkm) | ||||||
5263 | pRes->nSprmId = eFACTOIDBKN; | ||||||
5264 | else if( &m_aD[nIdx] == m_pPcd ) | ||||||
5265 | { | ||||||
5266 | //We slave the piece table attributes to the piece table, the piece | ||||||
5267 | //table attribute iterator contains the sprms for this piece. | ||||||
5268 | GetSprmEnd( nIdx+1, pRes ); | ||||||
5269 | } | ||||||
5270 | else | ||||||
5271 | pRes->nSprmId = 0; | ||||||
5272 | } | ||||||
5273 | |||||||
5274 | void WW8PLCFMan::TransferOpenSprms(std::stack<sal_uInt16> &rStack) | ||||||
5275 | { | ||||||
5276 | for (sal_uInt16 i = 0; i < m_nPLCF; ++i) | ||||||
5277 | { | ||||||
5278 | WW8PLCFxDesc* p = &m_aD[i]; | ||||||
5279 | if (!p || !p->pIdStack) | ||||||
5280 | continue; | ||||||
5281 | while (!p->pIdStack->empty()) | ||||||
5282 | { | ||||||
5283 | rStack.push(p->pIdStack->top()); | ||||||
5284 | p->pIdStack->pop(); | ||||||
5285 | } | ||||||
5286 | } | ||||||
5287 | } | ||||||
5288 | |||||||
5289 | void WW8PLCFMan::AdvSprm(short nIdx, bool bStart) | ||||||
5290 | { | ||||||
5291 | WW8PLCFxDesc* p = &m_aD[nIdx]; // determine sprm class(!) | ||||||
5292 | |||||||
5293 | p->bFirstSprm = false; | ||||||
5294 | if( bStart ) | ||||||
5295 | { | ||||||
5296 | const sal_uInt16 nLastId = GetId(p); | ||||||
5297 | p->pIdStack->push(nLastId); // remember Id for attribute end | ||||||
5298 | |||||||
5299 | if( p->nSprmsLen ) | ||||||
5300 | { /* | ||||||
5301 | Check, if we have to process more sprm(s). | ||||||
5302 | */ | ||||||
5303 | if( p->pMemPos ) | ||||||
5304 | { | ||||||
5305 | // Length of last sprm | ||||||
5306 | const sal_Int32 nSprmL = maSprmParser.GetSprmSize(nLastId, p->pMemPos, p->nSprmsLen); | ||||||
5307 | |||||||
5308 | // Reduce length of all sprms by length of last sprm | ||||||
5309 | p->nSprmsLen -= nSprmL; | ||||||
5310 | |||||||
5311 | // pos of next possible sprm | ||||||
5312 | if (p->nSprmsLen < maSprmParser.MinSprmLen()) | ||||||
5313 | { | ||||||
5314 | // preventively set to 0, because the end follows! | ||||||
5315 | p->pMemPos = nullptr; | ||||||
5316 | p->nSprmsLen = 0; | ||||||
5317 | } | ||||||
5318 | else | ||||||
5319 | p->pMemPos += nSprmL; | ||||||
5320 | } | ||||||
5321 | else | ||||||
5322 | p->nSprmsLen = 0; | ||||||
5323 | } | ||||||
5324 | if (p->nSprmsLen < maSprmParser.MinSprmLen()) | ||||||
5325 | p->nStartPos = WW8_CP_MAX; // the ending follows | ||||||
5326 | } | ||||||
5327 | else | ||||||
5328 | { | ||||||
5329 | if (!(p->pIdStack->empty())) | ||||||
5330 | p->pIdStack->pop(); | ||||||
5331 | if (p->pIdStack->empty()) | ||||||
5332 | { | ||||||
5333 | if ( (p == m_pChp) || (p == m_pPap) ) | ||||||
5334 | { | ||||||
5335 | p->pMemPos = nullptr; | ||||||
5336 | p->nSprmsLen = 0; | ||||||
5337 | p->nStartPos = p->nOrigEndPos+p->nCpOfs; | ||||||
5338 | |||||||
5339 | /* | ||||||
5340 | On failed seek we have run out of sprms, probably. But if its | ||||||
5341 | a fastsaved file (has pPcd) then we may be just in a sprm free | ||||||
5342 | gap between pieces that have them, so set dirty flag in sprm | ||||||
5343 | finder to consider than. | ||||||
5344 | */ | ||||||
5345 | if (!(*p->pPLCFx).SeekPos(p->nStartPos)) | ||||||
5346 | { | ||||||
5347 | p->nEndPos = WW8_CP_MAX; | ||||||
5348 | p->pPLCFx->SetDirty(true); | ||||||
5349 | } | ||||||
5350 | if (!p->pPLCFx->GetDirty() || m_pPcd) | ||||||
5351 | GetNewSprms( *p ); | ||||||
5352 | p->pPLCFx->SetDirty(false); | ||||||
5353 | |||||||
5354 | /* | ||||||
5355 | #i2325# | ||||||
5356 | To get the character and paragraph properties you first get | ||||||
5357 | the pap and chp and then apply the fastsaved pPcd properties | ||||||
5358 | to the range. If a pap or chp starts inside the pPcd range | ||||||
5359 | then we must bring the current pPcd range to a halt so as to | ||||||
5360 | end those sprms, then the pap/chp will be processed, and then | ||||||
5361 | we must force a restart of the pPcd on that pap/chp starting | ||||||
5362 | boundary. Doing that effectively means that the pPcd sprms will | ||||||
5363 | be applied to the new range. Not doing it means that the pPcd | ||||||
5364 | sprms will only be applied to the first pap/chp set of | ||||||
5365 | properties contained in the pap/chp range. | ||||||
5366 | |||||||
5367 | So we bring the pPcd to a halt on this location here, by | ||||||
5368 | settings its end to the current start, then store the starting | ||||||
5369 | position of the current range to clipstart. The pPcd sprms | ||||||
5370 | will end as normal (albeit earlier than originally expected), | ||||||
5371 | and the existence of a clipstart will force the pPcd iterator | ||||||
5372 | to reread the current set of sprms instead of advancing to its | ||||||
5373 | next set. Then the clipstart will be set as the starting | ||||||
5374 | position which will force them to be applied directly after | ||||||
5375 | the pap and chps. | ||||||
5376 | */ | ||||||
5377 | if (m_pPcd && ((p->nStartPos > m_pPcd->nStartPos) || | ||||||
5378 | (m_pPcd->nStartPos == WW8_CP_MAX)) && | ||||||
5379 | (m_pPcd->nEndPos != p->nStartPos)) | ||||||
5380 | { | ||||||
5381 | m_pPcd->nEndPos = p->nStartPos; | ||||||
5382 | static_cast<WW8PLCFx_PCD *>(m_pPcd->pPLCFx)->SetClipStart( | ||||||
5383 | p->nStartPos); | ||||||
5384 | } | ||||||
5385 | |||||||
5386 | } | ||||||
5387 | else | ||||||
5388 | { | ||||||
5389 | p->pPLCFx->advance(); // next Group of Sprms | ||||||
5390 | p->pMemPos = nullptr; // !!! | ||||||
5391 | p->nSprmsLen = 0; | ||||||
5392 | GetNewSprms( *p ); | ||||||
5393 | } | ||||||
5394 | SAL_WARN_IF(p->nStartPos > p->nEndPos, "sw.ww8",do { if (true && (p->nStartPos > p->nEndPos) ) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << p-> nEndPos << " before Start " << p->nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << p->nEndPos << " before Start " << p->nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << p->nEndPos << " before Start " << p->nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << p->nEndPos << " before Start " << p->nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << p->nEndPos << " before Start " << p->nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << p->nEndPos << " before Start " << p->nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
5395 | "End " << p->nEndPos << " before Start " << p->nStartPos)do { if (true && (p->nStartPos > p->nEndPos) ) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << p-> nEndPos << " before Start " << p->nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << p->nEndPos << " before Start " << p->nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << p->nEndPos << " before Start " << p->nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << p->nEndPos << " before Start " << p->nStartPos) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << p->nEndPos << " before Start " << p->nStartPos), 0); } else { ::std ::ostringstream sal_detail_stream; sal_detail_stream << "End " << p->nEndPos << " before Start " << p->nStartPos; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5395" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5396 | } | ||||||
5397 | } | ||||||
5398 | } | ||||||
5399 | |||||||
5400 | void WW8PLCFMan::AdvNoSprm(short nIdx, bool bStart) | ||||||
5401 | { | ||||||
5402 | /* | ||||||
5403 | For the case of a piece table we slave the piece table attribute iterator | ||||||
5404 | to the piece table and access it through that only. They are two separate | ||||||
5405 | structures, but act together as one logical one. The attributes only go | ||||||
5406 | to the next entry when the piece changes | ||||||
5407 | */ | ||||||
5408 | WW8PLCFxDesc* p = &m_aD[nIdx]; | ||||||
5409 | |||||||
5410 | if( p == m_pPcd ) | ||||||
5411 | { | ||||||
5412 | AdvSprm(nIdx+1,bStart); | ||||||
5413 | if( bStart ) | ||||||
5414 | p->nStartPos = m_aD[nIdx+1].nStartPos; | ||||||
5415 | else | ||||||
5416 | { | ||||||
5417 | if (m_aD[nIdx+1].pIdStack->empty()) | ||||||
5418 | { | ||||||
5419 | WW8PLCFx_PCD *pTemp = static_cast<WW8PLCFx_PCD*>(m_pPcd->pPLCFx); | ||||||
5420 | /* | ||||||
5421 | #i2325# | ||||||
5422 | As per normal, go on to the next set of properties, i.e. we | ||||||
5423 | have traversed over to the next piece. With a clipstart set | ||||||
5424 | we are being told to reread the current piece sprms so as to | ||||||
5425 | reapply them to a new chp or pap range. | ||||||
5426 | */ | ||||||
5427 | if (pTemp->GetClipStart() == -1) | ||||||
5428 | p->pPLCFx->advance(); | ||||||
5429 | p->pMemPos = nullptr; | ||||||
5430 | p->nSprmsLen = 0; | ||||||
5431 | GetNewSprms( m_aD[nIdx+1] ); | ||||||
5432 | GetNewNoSprms( *p ); | ||||||
5433 | if (pTemp->GetClipStart() != -1) | ||||||
5434 | { | ||||||
5435 | /* | ||||||
5436 | #i2325#, now we will force our starting position to the | ||||||
5437 | clipping start so as to force the application of these | ||||||
5438 | sprms after the current pap/chp sprms so as to apply the | ||||||
5439 | fastsave sprms to the current range. | ||||||
5440 | */ | ||||||
5441 | p->nStartPos = pTemp->GetClipStart(); | ||||||
5442 | pTemp->SetClipStart(-1); | ||||||
5443 | } | ||||||
5444 | } | ||||||
5445 | } | ||||||
5446 | } | ||||||
5447 | else | ||||||
5448 | { // NoSprm without end | ||||||
5449 | p->pPLCFx->advance(); | ||||||
5450 | p->pMemPos = nullptr; // MemPos invalid | ||||||
5451 | p->nSprmsLen = 0; | ||||||
5452 | GetNewNoSprms( *p ); | ||||||
5453 | } | ||||||
5454 | } | ||||||
5455 | |||||||
5456 | void WW8PLCFMan::advance() | ||||||
5457 | { | ||||||
5458 | bool bStart; | ||||||
5459 | const sal_uInt16 nIdx = WhereIdx(&bStart); | ||||||
5460 | if (nIdx < m_nPLCF) | ||||||
5461 | { | ||||||
5462 | WW8PLCFxDesc* p = &m_aD[nIdx]; | ||||||
5463 | |||||||
5464 | p->bFirstSprm = true; // Default | ||||||
5465 | |||||||
5466 | if( p->pPLCFx->IsSprm() ) | ||||||
5467 | AdvSprm( nIdx, bStart ); | ||||||
5468 | else // NoSprm | ||||||
5469 | AdvNoSprm( nIdx, bStart ); | ||||||
5470 | } | ||||||
5471 | } | ||||||
5472 | |||||||
5473 | // return true for the beginning of an attribute or error, | ||||||
5474 | // false for the end of an attribute | ||||||
5475 | // remaining return values are delivered to the caller from WW8PclxManResults. | ||||||
5476 | bool WW8PLCFMan::Get(WW8PLCFManResult* pRes) const | ||||||
5477 | { | ||||||
5478 | memset( pRes, 0, sizeof( WW8PLCFManResult ) ); | ||||||
5479 | bool bStart; | ||||||
5480 | const sal_uInt16 nIdx = WhereIdx(&bStart); | ||||||
5481 | |||||||
5482 | if( nIdx >= m_nPLCF ) | ||||||
5483 | { | ||||||
5484 | OSL_ENSURE( false, "Position not found" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5484" ": "), "%s", "Position not found"); } } while (false ); | ||||||
5485 | return true; | ||||||
5486 | } | ||||||
5487 | |||||||
5488 | if( m_aD[nIdx].pPLCFx->IsSprm() ) | ||||||
5489 | { | ||||||
5490 | if( bStart ) | ||||||
5491 | { | ||||||
5492 | GetSprmStart( nIdx, pRes ); | ||||||
5493 | return true; | ||||||
5494 | } | ||||||
5495 | else | ||||||
5496 | { | ||||||
5497 | GetSprmEnd( nIdx, pRes ); | ||||||
5498 | return false; | ||||||
5499 | } | ||||||
5500 | } | ||||||
5501 | else | ||||||
5502 | { | ||||||
5503 | if( bStart ) | ||||||
5504 | { | ||||||
5505 | GetNoSprmStart( nIdx, pRes ); | ||||||
5506 | return true; | ||||||
5507 | } | ||||||
5508 | else | ||||||
5509 | { | ||||||
5510 | GetNoSprmEnd( nIdx, pRes ); | ||||||
5511 | return false; | ||||||
5512 | } | ||||||
5513 | } | ||||||
5514 | } | ||||||
5515 | |||||||
5516 | sal_uInt16 WW8PLCFMan::GetColl() const | ||||||
5517 | { | ||||||
5518 | if( m_pPap->pPLCFx ) | ||||||
5519 | return m_pPap->pPLCFx->GetIstd(); | ||||||
5520 | else | ||||||
5521 | { | ||||||
5522 | OSL_ENSURE( false, "GetColl without PLCF_Pap" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5522" ": "), "%s", "GetColl without PLCF_Pap"); } } while (false); | ||||||
5523 | return 0; | ||||||
5524 | } | ||||||
5525 | } | ||||||
5526 | |||||||
5527 | WW8PLCFx_FLD* WW8PLCFMan::GetField() const | ||||||
5528 | { | ||||||
5529 | return static_cast<WW8PLCFx_FLD*>(m_pField->pPLCFx); | ||||||
5530 | } | ||||||
5531 | |||||||
5532 | SprmResult WW8PLCFMan::HasParaSprm( sal_uInt16 nId ) const | ||||||
5533 | { | ||||||
5534 | return static_cast<WW8PLCFx_Cp_FKP*>(m_pPap->pPLCFx)->HasSprm( nId ); | ||||||
5535 | } | ||||||
5536 | |||||||
5537 | SprmResult WW8PLCFMan::HasCharSprm( sal_uInt16 nId ) const | ||||||
5538 | { | ||||||
5539 | return static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm( nId ); | ||||||
5540 | } | ||||||
5541 | |||||||
5542 | void WW8PLCFMan::HasCharSprm(sal_uInt16 nId, | ||||||
5543 | std::vector<SprmResult> &rResult) const | ||||||
5544 | { | ||||||
5545 | static_cast<WW8PLCFx_Cp_FKP*>(m_pChp->pPLCFx)->HasSprm(nId, rResult); | ||||||
5546 | } | ||||||
5547 | |||||||
5548 | void WW8PLCFx::Save( WW8PLCFxSave1& rSave ) const | ||||||
5549 | { | ||||||
5550 | rSave.nPLCFxPos = GetIdx(); | ||||||
5551 | rSave.nPLCFxPos2 = GetIdx2(); | ||||||
5552 | rSave.nPLCFxMemOfs = 0; | ||||||
5553 | rSave.nStartFC = GetStartFc(); | ||||||
5554 | } | ||||||
5555 | |||||||
5556 | void WW8PLCFx::Restore( const WW8PLCFxSave1& rSave ) | ||||||
5557 | { | ||||||
5558 | SetIdx( rSave.nPLCFxPos ); | ||||||
5559 | SetIdx2( rSave.nPLCFxPos2 ); | ||||||
5560 | SetStartFc( rSave.nStartFC ); | ||||||
5561 | } | ||||||
5562 | |||||||
5563 | sal_uInt32 WW8PLCFx_Cp_FKP::GetIdx2() const | ||||||
5564 | { | ||||||
5565 | return GetPCDIdx(); | ||||||
5566 | } | ||||||
5567 | |||||||
5568 | void WW8PLCFx_Cp_FKP::SetIdx2(sal_uInt32 nIdx) | ||||||
5569 | { | ||||||
5570 | if( pPcd ) | ||||||
5571 | pPcd->SetIdx( nIdx ); | ||||||
5572 | } | ||||||
5573 | |||||||
5574 | void WW8PLCFx_Cp_FKP::Save( WW8PLCFxSave1& rSave ) const | ||||||
5575 | { | ||||||
5576 | if (pFkp) | ||||||
5577 | pFkp->IncMustRemainCache(); | ||||||
5578 | WW8PLCFx::Save( rSave ); | ||||||
5579 | |||||||
5580 | rSave.nAttrStart = nAttrStart; | ||||||
5581 | rSave.nAttrEnd = nAttrEnd; | ||||||
5582 | rSave.bLineEnd = bLineEnd; | ||||||
5583 | } | ||||||
5584 | |||||||
5585 | void WW8PLCFx_Cp_FKP::Restore( const WW8PLCFxSave1& rSave ) | ||||||
5586 | { | ||||||
5587 | WW8PLCFx::Restore( rSave ); | ||||||
5588 | |||||||
5589 | nAttrStart = rSave.nAttrStart; | ||||||
5590 | nAttrEnd = rSave.nAttrEnd; | ||||||
5591 | bLineEnd = rSave.bLineEnd; | ||||||
5592 | |||||||
5593 | if (pFkp) | ||||||
5594 | pFkp->DecMustRemainCache(); | ||||||
5595 | } | ||||||
5596 | |||||||
5597 | void WW8PLCFxDesc::Save( WW8PLCFxSave1& rSave ) const | ||||||
5598 | { | ||||||
5599 | if( !pPLCFx ) | ||||||
5600 | return; | ||||||
5601 | |||||||
5602 | pPLCFx->Save( rSave ); | ||||||
5603 | if( !pPLCFx->IsSprm() ) | ||||||
5604 | return; | ||||||
5605 | |||||||
5606 | WW8PLCFxDesc aD; | ||||||
5607 | aD.nStartPos = nOrigStartPos+nCpOfs; | ||||||
5608 | aD.nCpOfs = rSave.nCpOfs = nCpOfs; | ||||||
5609 | if (!(pPLCFx->SeekPos(aD.nStartPos))) | ||||||
5610 | { | ||||||
5611 | aD.nEndPos = WW8_CP_MAX; | ||||||
5612 | pPLCFx->SetDirty(true); | ||||||
5613 | } | ||||||
5614 | pPLCFx->GetSprms(&aD); | ||||||
5615 | pPLCFx->SetDirty(false); | ||||||
5616 | aD.ReduceByOffset(); | ||||||
5617 | rSave.nStartCp = aD.nStartPos; | ||||||
5618 | rSave.nPLCFxMemOfs = nOrigSprmsLen - nSprmsLen; | ||||||
5619 | } | ||||||
5620 | |||||||
5621 | void WW8PLCFxDesc::Restore( const WW8PLCFxSave1& rSave ) | ||||||
5622 | { | ||||||
5623 | if( !pPLCFx ) | ||||||
5624 | return; | ||||||
5625 | |||||||
5626 | pPLCFx->Restore( rSave ); | ||||||
5627 | if( !pPLCFx->IsSprm() ) | ||||||
5628 | return; | ||||||
5629 | |||||||
5630 | WW8PLCFxDesc aD; | ||||||
5631 | aD.nStartPos = rSave.nStartCp+rSave.nCpOfs; | ||||||
5632 | nCpOfs = aD.nCpOfs = rSave.nCpOfs; | ||||||
5633 | if (!(pPLCFx->SeekPos(aD.nStartPos))) | ||||||
5634 | { | ||||||
5635 | aD.nEndPos = WW8_CP_MAX; | ||||||
5636 | pPLCFx->SetDirty(true); | ||||||
5637 | } | ||||||
5638 | pPLCFx->GetSprms(&aD); | ||||||
5639 | pPLCFx->SetDirty(false); | ||||||
5640 | aD.ReduceByOffset(); | ||||||
5641 | |||||||
5642 | if (nOrigSprmsLen > aD.nSprmsLen) | ||||||
5643 | { | ||||||
5644 | //two entries exist for the same offset, cut and run | ||||||
5645 | SAL_WARN("sw.ww8", "restored properties don't match saved properties, bailing out")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "restored properties don't match saved properties, bailing out" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5645" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "restored properties don't match saved properties, bailing out" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "restored properties don't match saved properties, bailing out" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5645" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "restored properties don't match saved properties, bailing out" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5645" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "restored properties don't match saved properties, bailing out" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "restored properties don't match saved properties, bailing out" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5645" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
5646 | nSprmsLen = 0; | ||||||
5647 | pMemPos = nullptr; | ||||||
5648 | } | ||||||
5649 | else | ||||||
5650 | { | ||||||
5651 | nSprmsLen = nOrigSprmsLen - rSave.nPLCFxMemOfs; | ||||||
5652 | pMemPos = aD.pMemPos == nullptr ? nullptr : aD.pMemPos + rSave.nPLCFxMemOfs; | ||||||
5653 | } | ||||||
5654 | } | ||||||
5655 | |||||||
5656 | namespace | ||||||
5657 | { | ||||||
5658 | sal_uInt32 Readcb(SvStream& rSt, ww::WordVersion eVer) | ||||||
5659 | { | ||||||
5660 | if (eVer <= ww::eWW2) | ||||||
5661 | { | ||||||
5662 | sal_uInt16 nShort(0); | ||||||
5663 | rSt.ReadUInt16(nShort); | ||||||
5664 | return nShort; | ||||||
5665 | } | ||||||
5666 | else | ||||||
5667 | { | ||||||
5668 | sal_uInt32 nLong(0); | ||||||
5669 | rSt.ReadUInt32(nLong); | ||||||
5670 | return nLong; | ||||||
5671 | } | ||||||
5672 | } | ||||||
5673 | } | ||||||
5674 | |||||||
5675 | bool WW8Fib::GetBaseCp(ManTypes nType, WW8_CP * cp) const | ||||||
5676 | { | ||||||
5677 | assert(cp != nullptr)(static_cast <bool> (cp != nullptr) ? void (0) : __assert_fail ("cp != nullptr", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 5677, __extension__ __PRETTY_FUNCTION__)); | ||||||
5678 | WW8_CP nOffset = 0; | ||||||
5679 | |||||||
5680 | switch (nType) | ||||||
5681 | { | ||||||
5682 | case MAN_TXBX_HDFT: | ||||||
5683 | if (m_ccpTxbx < 0) { | ||||||
5684 | return false; | ||||||
5685 | } | ||||||
5686 | nOffset = m_ccpTxbx; | ||||||
5687 | [[fallthrough]]; | ||||||
5688 | case MAN_TXBX: | ||||||
5689 | if (m_ccpEdn < 0 || m_ccpEdn > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5690 | return false; | ||||||
5691 | } | ||||||
5692 | nOffset += m_ccpEdn; | ||||||
5693 | [[fallthrough]]; | ||||||
5694 | case MAN_EDN: | ||||||
5695 | if (m_ccpAtn < 0 || m_ccpAtn > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5696 | return false; | ||||||
5697 | } | ||||||
5698 | nOffset += m_ccpAtn; | ||||||
5699 | [[fallthrough]]; | ||||||
5700 | case MAN_AND: | ||||||
5701 | if (m_ccpMcr < 0 || m_ccpMcr > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5702 | return false; | ||||||
5703 | } | ||||||
5704 | nOffset += m_ccpMcr; | ||||||
5705 | /* | ||||||
5706 | // fall through | ||||||
5707 | |||||||
5708 | A subdocument of this kind (MAN_MACRO) probably exists in some defunct | ||||||
5709 | version of MSWord, but now ccpMcr is always 0. If some example that | ||||||
5710 | uses this comes to light, this is the likely calculation required | ||||||
5711 | |||||||
5712 | case MAN_MACRO: | ||||||
5713 | */ | ||||||
5714 | if (m_ccpHdr < 0 || m_ccpHdr > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5715 | return false; | ||||||
5716 | } | ||||||
5717 | nOffset += m_ccpHdr; | ||||||
5718 | [[fallthrough]]; | ||||||
5719 | case MAN_HDFT: | ||||||
5720 | if (m_ccpFootnote < 0 || m_ccpFootnote > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5721 | return false; | ||||||
5722 | } | ||||||
5723 | nOffset += m_ccpFootnote; | ||||||
5724 | [[fallthrough]]; | ||||||
5725 | case MAN_FTN: | ||||||
5726 | if (m_ccpText < 0 || m_ccpText > std::numeric_limits<WW8_CP>::max() - nOffset) { | ||||||
5727 | return false; | ||||||
5728 | } | ||||||
5729 | nOffset += m_ccpText; | ||||||
5730 | [[fallthrough]]; | ||||||
5731 | case MAN_MAINTEXT: | ||||||
5732 | break; | ||||||
5733 | } | ||||||
5734 | *cp = nOffset; | ||||||
5735 | return true; | ||||||
5736 | } | ||||||
5737 | |||||||
5738 | ww::WordVersion WW8Fib::GetFIBVersion() const | ||||||
5739 | { | ||||||
5740 | ww::WordVersion eVer = ww::eWW8; | ||||||
5741 | /* | ||||||
5742 | * Word for Windows 2 I think (1.X might work too if anyone has an example. | ||||||
5743 | * | ||||||
5744 | * 0xA59B for Word 1 for Windows | ||||||
5745 | * 0xA59C for Word 1 for OS/2 "PM Word" | ||||||
5746 | * | ||||||
5747 | * Various pages claim that the fileformats of Word 1 and 2 for Windows are | ||||||
5748 | * equivalent to Word for Macintosh 4 and 5. On the other hand | ||||||
5749 | * | ||||||
5750 | * wIdents for Word for Mac versions... | ||||||
5751 | * 0xFE32 for Word 1 | ||||||
5752 | * 0xFE34 for Word 3 | ||||||
5753 | * 0xFE37 for Word 4 et 5. | ||||||
5754 | * | ||||||
5755 | * and this document | ||||||
5756 | * http://cmsdoc.cern.ch/documents/docformat/CMS_CERN_LetterHead.word is | ||||||
5757 | * claimed to be "Word 5 for Mac" by Office etc and has that wIdent, but | ||||||
5758 | * its format isn't the same as that of Word 2 for windows. Nor is it | ||||||
5759 | * the same as that of Word for DOS/PCWord 5 | ||||||
5760 | */ | ||||||
5761 | if (m_wIdent == 0xa59b || m_wIdent == 0xa59c) | ||||||
5762 | eVer = ww::eWW1; | ||||||
5763 | else if (m_wIdent == 0xa5db) | ||||||
5764 | eVer = ww::eWW2; | ||||||
5765 | else | ||||||
5766 | { | ||||||
5767 | switch (m_nVersion) | ||||||
5768 | { | ||||||
5769 | case 6: | ||||||
5770 | eVer = ww::eWW6; | ||||||
5771 | break; | ||||||
5772 | case 7: | ||||||
5773 | eVer = ww::eWW7; | ||||||
5774 | break; | ||||||
5775 | case 8: | ||||||
5776 | eVer = ww::eWW8; | ||||||
5777 | break; | ||||||
5778 | } | ||||||
5779 | } | ||||||
5780 | return eVer; | ||||||
5781 | } | ||||||
5782 | |||||||
5783 | WW8Fib::WW8Fib(SvStream& rSt, sal_uInt8 nWantedVersion, sal_uInt32 nOffset): | ||||||
5784 | m_fDot(false), m_fGlsy(false), m_fComplex(false), m_fHasPic(false), m_cQuickSaves(0), | ||||||
5785 | m_fEncrypted(false), m_fWhichTableStm(false), m_fReadOnlyRecommended(false), | ||||||
5786 | m_fWriteReservation(false), m_fExtChar(false), m_fFarEast(false), m_fObfuscated(false), | ||||||
5787 | m_fMac(false), m_fEmptySpecial(false), m_fLoadOverridePage(false), m_fFuturesavedUndo(false), | ||||||
5788 | m_fWord97Saved(false), m_fWord2000Saved(false) | ||||||
5789 | // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the | ||||||
5790 | // above bit-field member initializations can be moved to the class definition | ||||||
5791 | { | ||||||
5792 | // See [MS-DOC] 2.5.15 "How to read the FIB". | ||||||
5793 | sal_uInt8 aBits1; | ||||||
5794 | sal_uInt8 aBits2; | ||||||
5795 | sal_uInt8 aVer8Bits1; // only used starting with WinWord 8 | ||||||
5796 | rSt.Seek( nOffset ); | ||||||
5797 | /* | ||||||
5798 | note desired number, identify file version number | ||||||
5799 | and check against desired number! | ||||||
5800 | */ | ||||||
5801 | m_nVersion = nWantedVersion; | ||||||
5802 | rSt.ReadUInt16( m_wIdent ); | ||||||
5803 | rSt.ReadUInt16( m_nFib ); | ||||||
5804 | rSt.ReadUInt16( m_nProduct ); | ||||||
5805 | if( ERRCODE_NONEErrCode(0) != rSt.GetError() ) | ||||||
5806 | { | ||||||
5807 | sal_Int16 nFibMin; | ||||||
5808 | sal_Int16 nFibMax; | ||||||
5809 | // note: 6 stands for "6 OR 7", 7 stands for "ONLY 7" | ||||||
5810 | switch( m_nVersion ) | ||||||
5811 | { | ||||||
5812 | case 6: | ||||||
5813 | nFibMin = 0x0065; // from 101 WinWord 6.0 | ||||||
5814 | // 102 " | ||||||
5815 | // and 103 WinWord 6.0 for Macintosh | ||||||
5816 | // 104 " | ||||||
5817 | nFibMax = 0x0069; // to 105 WinWord 95 | ||||||
5818 | break; | ||||||
5819 | case 7: | ||||||
5820 | nFibMin = 0x0069; // from 105 WinWord 95 | ||||||
5821 | nFibMax = 0x0069; // to 105 WinWord 95 | ||||||
5822 | break; | ||||||
5823 | case 8: | ||||||
5824 | nFibMin = 0x006A; // from 106 WinWord 97 | ||||||
5825 | nFibMax = 0x00c1; // to 193 WinWord 97 (?) | ||||||
5826 | break; | ||||||
5827 | default: | ||||||
5828 | nFibMin = 0; // program error! | ||||||
5829 | nFibMax = 0; | ||||||
5830 | m_nFib = 1; | ||||||
5831 | OSL_ENSURE( false, "nVersion not implemented!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "5831" ": "), "%s", "nVersion not implemented!"); } } while (false); | ||||||
5832 | break; | ||||||
5833 | } | ||||||
5834 | if ( (m_nFib < nFibMin) || (m_nFib > nFibMax) ) | ||||||
5835 | { | ||||||
5836 | m_nFibError = ERR_SWG_READ_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Read, 2 ); // report error | ||||||
5837 | return; | ||||||
5838 | } | ||||||
5839 | } | ||||||
5840 | |||||||
5841 | ww::WordVersion eVer = GetFIBVersion(); | ||||||
5842 | |||||||
5843 | // helper vars for Ver67: | ||||||
5844 | sal_Int16 pnChpFirst_Ver67=0; | ||||||
5845 | sal_Int16 pnPapFirst_Ver67=0; | ||||||
5846 | sal_Int16 cpnBteChp_Ver67=0; | ||||||
5847 | sal_Int16 cpnBtePap_Ver67=0; | ||||||
5848 | |||||||
5849 | // read FIB | ||||||
5850 | sal_uInt16 nTmpLid = 0; | ||||||
5851 | rSt.ReadUInt16(nTmpLid); | ||||||
5852 | m_lid = LanguageType(nTmpLid); | ||||||
5853 | rSt.ReadInt16( m_pnNext ); | ||||||
5854 | rSt.ReadUChar( aBits1 ); | ||||||
5855 | rSt.ReadUChar( aBits2 ); | ||||||
5856 | rSt.ReadUInt16( m_nFibBack ); | ||||||
5857 | rSt.ReadUInt16( m_nHash ); | ||||||
5858 | rSt.ReadUInt16( m_nKey ); | ||||||
5859 | rSt.ReadUChar( m_envr ); | ||||||
5860 | rSt.ReadUChar( aVer8Bits1 ); // only have an empty reserve field under Ver67 | ||||||
5861 | // content from aVer8Bits1 | ||||||
5862 | |||||||
5863 | // sal_uInt8 fMac :1; | ||||||
5864 | // sal_uInt8 fEmptySpecial :1; | ||||||
5865 | // sal_uInt8 fLoadOverridePage :1; | ||||||
5866 | // sal_uInt8 fFuturesavedUndo :1; | ||||||
5867 | // sal_uInt8 fWord97Saved :1; | ||||||
5868 | // sal_uInt8 :3; | ||||||
5869 | rSt.ReadUInt16( m_chse ); | ||||||
5870 | rSt.ReadUInt16( m_chseTables ); | ||||||
5871 | rSt.ReadInt32( m_fcMin ); | ||||||
5872 | rSt.ReadInt32( m_fcMac ); | ||||||
5873 | |||||||
5874 | // insertion for WW8 | ||||||
5875 | if (IsEightPlus(eVer)) | ||||||
5876 | { | ||||||
5877 | rSt.ReadUInt16( m_csw ); | ||||||
5878 | |||||||
5879 | // Marke: "rgsw" Beginning of the array of shorts | ||||||
5880 | rSt.ReadUInt16( m_wMagicCreated ); | ||||||
5881 | rSt.ReadUInt16( m_wMagicRevised ); | ||||||
5882 | rSt.ReadUInt16( m_wMagicCreatedPrivate ); | ||||||
5883 | rSt.ReadUInt16( m_wMagicRevisedPrivate ); | ||||||
5884 | rSt.SeekRel( 9 * sizeof( sal_Int16 ) ); | ||||||
5885 | |||||||
5886 | /* | ||||||
5887 | // these are the 9 unused fields: | ||||||
5888 | && (bVer67 || WW8ReadINT16( rSt, pnFbpChpFirst_W6 )) // 1 | ||||||
5889 | && (bVer67 || WW8ReadINT16( rSt, pnChpFirst_W6 )) // 2 | ||||||
5890 | && (bVer67 || WW8ReadINT16( rSt, cpnBteChp_W6 )) // 3 | ||||||
5891 | && (bVer67 || WW8ReadINT16( rSt, pnFbpPapFirst_W6 )) // 4 | ||||||
5892 | && (bVer67 || WW8ReadINT16( rSt, pnPapFirst_W6 )) // 5 | ||||||
5893 | && (bVer67 || WW8ReadINT16( rSt, cpnBtePap_W6 )) // 6 | ||||||
5894 | && (bVer67 || WW8ReadINT16( rSt, pnFbpLvcFirst_W6 )) // 7 | ||||||
5895 | && (bVer67 || WW8ReadINT16( rSt, pnLvcFirst_W6 )) // 8 | ||||||
5896 | && (bVer67 || WW8ReadINT16( rSt, cpnBteLvc_W6 )) // 9 | ||||||
5897 | */ | ||||||
5898 | sal_uInt16 nTmpFE = 0; | ||||||
5899 | rSt.ReadUInt16(nTmpFE); | ||||||
5900 | m_lidFE = LanguageType(nTmpFE); | ||||||
5901 | rSt.ReadUInt16( m_clw ); | ||||||
5902 | } | ||||||
5903 | |||||||
5904 | // end of the insertion for WW8 | ||||||
5905 | |||||||
5906 | // Marke: "rglw" Beginning of the array of longs | ||||||
5907 | rSt.ReadInt32( m_cbMac ); | ||||||
5908 | |||||||
5909 | // ignore 2 longs, because they are unimportant | ||||||
5910 | rSt.SeekRel( 2 * sizeof( sal_Int32) ); | ||||||
5911 | |||||||
5912 | // skipping 2 more longs only at Ver67 | ||||||
5913 | if (IsSevenMinus(eVer)) | ||||||
5914 | rSt.SeekRel( 2 * sizeof( sal_Int32) ); | ||||||
5915 | |||||||
5916 | rSt.ReadInt32( m_ccpText ); | ||||||
5917 | rSt.ReadInt32( m_ccpFootnote ); | ||||||
5918 | rSt.ReadInt32( m_ccpHdr ); | ||||||
5919 | rSt.ReadInt32( m_ccpMcr ); | ||||||
5920 | rSt.ReadInt32( m_ccpAtn ); | ||||||
5921 | rSt.ReadInt32( m_ccpEdn ); | ||||||
5922 | rSt.ReadInt32( m_ccpTxbx ); | ||||||
5923 | rSt.ReadInt32( m_ccpHdrTxbx ); | ||||||
5924 | |||||||
5925 | // only skip one more long at Ver67 | ||||||
5926 | if (IsSevenMinus(eVer)) | ||||||
5927 | rSt.SeekRel( 1 * sizeof( sal_Int32) ); | ||||||
5928 | else | ||||||
5929 | { | ||||||
5930 | // insertion for WW8 | ||||||
5931 | rSt.ReadInt32( m_pnFbpChpFirst ); | ||||||
5932 | rSt.ReadInt32( m_pnChpFirst ); | ||||||
5933 | rSt.ReadInt32( m_cpnBteChp ); | ||||||
5934 | rSt.ReadInt32( m_pnFbpPapFirst ); | ||||||
5935 | rSt.ReadInt32( m_pnPapFirst ); | ||||||
5936 | rSt.ReadInt32( m_cpnBtePap ); | ||||||
5937 | rSt.ReadInt32( m_pnFbpLvcFirst ); | ||||||
5938 | rSt.ReadInt32( m_pnLvcFirst ); | ||||||
5939 | rSt.ReadInt32( m_cpnBteLvc ); | ||||||
5940 | rSt.ReadInt32( m_fcIslandFirst ); | ||||||
5941 | rSt.ReadInt32( m_fcIslandLim ); | ||||||
5942 | rSt.ReadUInt16( m_cfclcb ); | ||||||
5943 | |||||||
5944 | // Read cswNew to find out if nFib should be ignored. | ||||||
5945 | sal_uInt32 nPos = rSt.Tell(); | ||||||
5946 | rSt.SeekRel(m_cfclcb * 8); | ||||||
5947 | if (rSt.good()) | ||||||
5948 | { | ||||||
5949 | rSt.ReadUInt16(m_cswNew); | ||||||
5950 | } | ||||||
5951 | rSt.Seek(nPos); | ||||||
5952 | } | ||||||
5953 | |||||||
5954 | // end of the insertion for WW8 | ||||||
5955 | |||||||
5956 | // Marke: "rgfclcb" Beginning of array of FC/LCB pairs. | ||||||
5957 | rSt.ReadInt32( m_fcStshfOrig ); | ||||||
5958 | m_lcbStshfOrig = Readcb(rSt, eVer); | ||||||
5959 | rSt.ReadInt32( m_fcStshf ); | ||||||
5960 | m_lcbStshf = Readcb(rSt, eVer); | ||||||
5961 | rSt.ReadInt32( m_fcPlcffndRef ); | ||||||
5962 | m_lcbPlcffndRef = Readcb(rSt, eVer); | ||||||
5963 | rSt.ReadInt32( m_fcPlcffndText ); | ||||||
5964 | m_lcbPlcffndText = Readcb(rSt, eVer); | ||||||
5965 | rSt.ReadInt32( m_fcPlcfandRef ); | ||||||
5966 | m_lcbPlcfandRef = Readcb(rSt, eVer); | ||||||
5967 | rSt.ReadInt32( m_fcPlcfandText ); | ||||||
5968 | m_lcbPlcfandText = Readcb(rSt, eVer); | ||||||
5969 | rSt.ReadInt32( m_fcPlcfsed ); | ||||||
5970 | m_lcbPlcfsed = Readcb(rSt, eVer); | ||||||
5971 | rSt.ReadInt32( m_fcPlcfpad ); | ||||||
5972 | m_lcbPlcfpad = Readcb(rSt, eVer); | ||||||
5973 | rSt.ReadInt32( m_fcPlcfphe ); | ||||||
5974 | m_lcbPlcfphe = Readcb(rSt, eVer); | ||||||
5975 | rSt.ReadInt32( m_fcSttbfglsy ); | ||||||
5976 | m_lcbSttbfglsy = Readcb(rSt, eVer); | ||||||
5977 | rSt.ReadInt32( m_fcPlcfglsy ); | ||||||
5978 | m_lcbPlcfglsy = Readcb(rSt, eVer); | ||||||
5979 | rSt.ReadInt32( m_fcPlcfhdd ); | ||||||
5980 | m_lcbPlcfhdd = Readcb(rSt, eVer); | ||||||
5981 | rSt.ReadInt32( m_fcPlcfbteChpx ); | ||||||
5982 | m_lcbPlcfbteChpx = Readcb(rSt, eVer); | ||||||
5983 | rSt.ReadInt32( m_fcPlcfbtePapx ); | ||||||
5984 | m_lcbPlcfbtePapx = Readcb(rSt, eVer); | ||||||
5985 | rSt.ReadInt32( m_fcPlcfsea ); | ||||||
5986 | m_lcbPlcfsea = Readcb(rSt, eVer); | ||||||
5987 | rSt.ReadInt32( m_fcSttbfffn ); | ||||||
5988 | m_lcbSttbfffn = Readcb(rSt, eVer); | ||||||
5989 | rSt.ReadInt32( m_fcPlcffldMom ); | ||||||
5990 | m_lcbPlcffldMom = Readcb(rSt, eVer); | ||||||
5991 | rSt.ReadInt32( m_fcPlcffldHdr ); | ||||||
5992 | m_lcbPlcffldHdr = Readcb(rSt, eVer); | ||||||
5993 | rSt.ReadInt32( m_fcPlcffldFootnote ); | ||||||
5994 | m_lcbPlcffldFootnote = Readcb(rSt, eVer); | ||||||
5995 | rSt.ReadInt32( m_fcPlcffldAtn ); | ||||||
5996 | m_lcbPlcffldAtn = Readcb(rSt, eVer); | ||||||
5997 | rSt.ReadInt32( m_fcPlcffldMcr ); | ||||||
5998 | m_lcbPlcffldMcr = Readcb(rSt, eVer); | ||||||
5999 | rSt.ReadInt32( m_fcSttbfbkmk ); | ||||||
6000 | m_lcbSttbfbkmk = Readcb(rSt, eVer); | ||||||
6001 | rSt.ReadInt32( m_fcPlcfbkf ); | ||||||
6002 | m_lcbPlcfbkf = Readcb(rSt, eVer); | ||||||
6003 | rSt.ReadInt32( m_fcPlcfbkl ); | ||||||
6004 | m_lcbPlcfbkl = Readcb(rSt, eVer); | ||||||
6005 | rSt.ReadInt32( m_fcCmds ); | ||||||
6006 | m_lcbCmds = Readcb(rSt, eVer); | ||||||
6007 | rSt.ReadInt32( m_fcPlcfmcr ); | ||||||
6008 | m_lcbPlcfmcr = Readcb(rSt, eVer); | ||||||
6009 | rSt.ReadInt32( m_fcSttbfmcr ); | ||||||
6010 | m_lcbSttbfmcr = Readcb(rSt, eVer); | ||||||
6011 | if (eVer >= ww::eWW2) | ||||||
6012 | { | ||||||
6013 | rSt.ReadInt32( m_fcPrDrvr ); | ||||||
6014 | m_lcbPrDrvr = Readcb(rSt, eVer); | ||||||
6015 | rSt.ReadInt32( m_fcPrEnvPort ); | ||||||
6016 | m_lcbPrEnvPort = Readcb(rSt, eVer); | ||||||
6017 | rSt.ReadInt32( m_fcPrEnvLand ); | ||||||
6018 | m_lcbPrEnvLand = Readcb(rSt, eVer); | ||||||
6019 | } | ||||||
6020 | else | ||||||
6021 | { | ||||||
6022 | rSt.ReadInt32( m_fcPrEnvPort ); | ||||||
6023 | m_lcbPrEnvPort = Readcb(rSt, eVer); | ||||||
6024 | } | ||||||
6025 | rSt.ReadInt32( m_fcWss ); | ||||||
6026 | m_lcbWss = Readcb(rSt, eVer); | ||||||
6027 | rSt.ReadInt32( m_fcDop ); | ||||||
6028 | m_lcbDop = Readcb(rSt, eVer); | ||||||
6029 | rSt.ReadInt32( m_fcSttbfAssoc ); | ||||||
6030 | m_lcbSttbfAssoc = Readcb(rSt, eVer); | ||||||
6031 | rSt.ReadInt32( m_fcClx ); | ||||||
6032 | m_lcbClx = Readcb(rSt, eVer); | ||||||
6033 | rSt.ReadInt32( m_fcPlcfpgdFootnote ); | ||||||
6034 | m_lcbPlcfpgdFootnote = Readcb(rSt, eVer); | ||||||
6035 | rSt.ReadInt32( m_fcAutosaveSource ); | ||||||
6036 | m_lcbAutosaveSource = Readcb(rSt, eVer); | ||||||
6037 | rSt.ReadInt32( m_fcGrpStAtnOwners ); | ||||||
6038 | m_lcbGrpStAtnOwners = Readcb(rSt, eVer); | ||||||
6039 | rSt.ReadInt32( m_fcSttbfAtnbkmk ); | ||||||
6040 | m_lcbSttbfAtnbkmk = Readcb(rSt, eVer); | ||||||
6041 | |||||||
6042 | // only skip more shot at Ver67 | ||||||
6043 | if (IsSevenMinus(eVer)) | ||||||
6044 | { | ||||||
6045 | if (eVer == ww::eWW1) | ||||||
6046 | rSt.SeekRel(1*sizeof(sal_Int32)); | ||||||
6047 | rSt.SeekRel(1*sizeof(sal_Int16)); | ||||||
6048 | |||||||
6049 | if (eVer >= ww::eWW2) | ||||||
6050 | { | ||||||
6051 | rSt.ReadInt16(pnChpFirst_Ver67); | ||||||
6052 | rSt.ReadInt16(pnPapFirst_Ver67); | ||||||
6053 | } | ||||||
6054 | rSt.ReadInt16(cpnBteChp_Ver67); | ||||||
6055 | rSt.ReadInt16(cpnBtePap_Ver67); | ||||||
6056 | } | ||||||
6057 | |||||||
6058 | if (eVer > ww::eWW2) | ||||||
6059 | { | ||||||
6060 | rSt.ReadInt32( m_fcPlcfdoaMom ); | ||||||
6061 | rSt.ReadInt32( m_lcbPlcfdoaMom ); | ||||||
6062 | rSt.ReadInt32( m_fcPlcfdoaHdr ); | ||||||
6063 | rSt.ReadInt32( m_lcbPlcfdoaHdr ); | ||||||
6064 | rSt.ReadInt32( m_fcPlcfspaMom ); | ||||||
6065 | rSt.ReadInt32( m_lcbPlcfspaMom ); | ||||||
6066 | rSt.ReadInt32( m_fcPlcfspaHdr ); | ||||||
6067 | rSt.ReadInt32( m_lcbPlcfspaHdr ); | ||||||
6068 | |||||||
6069 | rSt.ReadInt32( m_fcPlcfAtnbkf ); | ||||||
6070 | rSt.ReadInt32( m_lcbPlcfAtnbkf ); | ||||||
6071 | rSt.ReadInt32( m_fcPlcfAtnbkl ); | ||||||
6072 | rSt.ReadInt32( m_lcbPlcfAtnbkl ); | ||||||
6073 | rSt.ReadInt32( m_fcPms ); | ||||||
6074 | rSt.ReadInt32( m_lcbPMS ); | ||||||
6075 | rSt.ReadInt32( m_fcFormFieldSttbf ); | ||||||
6076 | rSt.ReadInt32( m_lcbFormFieldSttbf ); | ||||||
6077 | rSt.ReadInt32( m_fcPlcfendRef ); | ||||||
6078 | rSt.ReadInt32( m_lcbPlcfendRef ); | ||||||
6079 | rSt.ReadInt32( m_fcPlcfendText ); | ||||||
6080 | rSt.ReadInt32( m_lcbPlcfendText ); | ||||||
6081 | rSt.ReadInt32( m_fcPlcffldEdn ); | ||||||
6082 | rSt.ReadInt32( m_lcbPlcffldEdn ); | ||||||
6083 | rSt.ReadInt32( m_fcPlcfpgdEdn ); | ||||||
6084 | rSt.ReadInt32( m_lcbPlcfpgdEdn ); | ||||||
6085 | rSt.ReadInt32( m_fcDggInfo ); | ||||||
6086 | rSt.ReadInt32( m_lcbDggInfo ); | ||||||
6087 | rSt.ReadInt32( m_fcSttbfRMark ); | ||||||
6088 | rSt.ReadInt32( m_lcbSttbfRMark ); | ||||||
6089 | rSt.ReadInt32( m_fcSttbfCaption ); | ||||||
6090 | rSt.ReadInt32( m_lcbSttbfCaption ); | ||||||
6091 | rSt.ReadInt32( m_fcSttbAutoCaption ); | ||||||
6092 | rSt.ReadInt32( m_lcbSttbAutoCaption ); | ||||||
6093 | rSt.ReadInt32( m_fcPlcfwkb ); | ||||||
6094 | rSt.ReadInt32( m_lcbPlcfwkb ); | ||||||
6095 | rSt.ReadInt32( m_fcPlcfspl ); | ||||||
6096 | rSt.ReadInt32( m_lcbPlcfspl ); | ||||||
6097 | rSt.ReadInt32( m_fcPlcftxbxText ); | ||||||
6098 | rSt.ReadInt32( m_lcbPlcftxbxText ); | ||||||
6099 | rSt.ReadInt32( m_fcPlcffldTxbx ); | ||||||
6100 | rSt.ReadInt32( m_lcbPlcffldTxbx ); | ||||||
6101 | rSt.ReadInt32( m_fcPlcfHdrtxbxText ); | ||||||
6102 | rSt.ReadInt32( m_lcbPlcfHdrtxbxText ); | ||||||
6103 | rSt.ReadInt32( m_fcPlcffldHdrTxbx ); | ||||||
6104 | rSt.ReadInt32( m_lcbPlcffldHdrTxbx ); | ||||||
6105 | rSt.ReadInt32( m_fcStwUser ); | ||||||
6106 | rSt.ReadUInt32( m_lcbStwUser ); | ||||||
6107 | rSt.ReadInt32( m_fcSttbttmbd ); | ||||||
6108 | rSt.ReadUInt32( m_lcbSttbttmbd ); | ||||||
6109 | } | ||||||
6110 | |||||||
6111 | if( ERRCODE_NONEErrCode(0) == rSt.GetError() ) | ||||||
6112 | { | ||||||
6113 | // set bit flag | ||||||
6114 | m_fDot = aBits1 & 0x01 ; | ||||||
6115 | m_fGlsy = ( aBits1 & 0x02 ) >> 1; | ||||||
6116 | m_fComplex = ( aBits1 & 0x04 ) >> 2; | ||||||
6117 | m_fHasPic = ( aBits1 & 0x08 ) >> 3; | ||||||
6118 | m_cQuickSaves = ( aBits1 & 0xf0 ) >> 4; | ||||||
6119 | m_fEncrypted = aBits2 & 0x01 ; | ||||||
6120 | m_fWhichTableStm= ( aBits2 & 0x02 ) >> 1; | ||||||
6121 | m_fReadOnlyRecommended = (aBits2 & 0x4) >> 2; | ||||||
6122 | m_fWriteReservation = (aBits2 & 0x8) >> 3; | ||||||
6123 | m_fExtChar = ( aBits2 & 0x10 ) >> 4; | ||||||
6124 | // dummy = ( aBits2 & 0x20 ) >> 5; | ||||||
6125 | m_fFarEast = ( aBits2 & 0x40 ) >> 6; // #i90932# | ||||||
6126 | // dummy = ( aBits2 & 0x80 ) >> 7; | ||||||
6127 | |||||||
6128 | /* | ||||||
6129 | p.r.n. fill targeted variable with xxx_Ver67 | ||||||
6130 | or set flags | ||||||
6131 | */ | ||||||
6132 | if (IsSevenMinus(eVer)) | ||||||
6133 | { | ||||||
6134 | m_pnChpFirst = pnChpFirst_Ver67; | ||||||
6135 | m_pnPapFirst = pnPapFirst_Ver67; | ||||||
6136 | m_cpnBteChp = cpnBteChp_Ver67; | ||||||
6137 | m_cpnBtePap = cpnBtePap_Ver67; | ||||||
6138 | } | ||||||
6139 | else if (IsEightPlus(eVer)) | ||||||
6140 | { | ||||||
6141 | m_fMac = aVer8Bits1 & 0x01 ; | ||||||
6142 | m_fEmptySpecial = ( aVer8Bits1 & 0x02 ) >> 1; | ||||||
6143 | m_fLoadOverridePage = ( aVer8Bits1 & 0x04 ) >> 2; | ||||||
6144 | m_fFuturesavedUndo = ( aVer8Bits1 & 0x08 ) >> 3; | ||||||
6145 | m_fWord97Saved = ( aVer8Bits1 & 0x10 ) >> 4; | ||||||
6146 | m_fWord2000Saved = ( aVer8Bits1 & 0x20 ) >> 5; | ||||||
6147 | |||||||
6148 | /* | ||||||
6149 | especially for WW8: | ||||||
6150 | identify the values for PLCF and PLF LFO | ||||||
6151 | and PLCF for the textbox break descriptors | ||||||
6152 | */ | ||||||
6153 | long nOldPos = rSt.Tell(); | ||||||
6154 | |||||||
6155 | rSt.Seek( 0x02da ); | ||||||
6156 | rSt.ReadInt32( m_fcSttbFnm ); | ||||||
6157 | rSt.ReadInt32( m_lcbSttbFnm ); | ||||||
6158 | rSt.ReadInt32( m_fcPlcfLst ); | ||||||
6159 | rSt.ReadInt32( m_lcbPlcfLst ); | ||||||
6160 | rSt.ReadInt32( m_fcPlfLfo ); | ||||||
6161 | rSt.ReadInt32( m_lcbPlfLfo ); | ||||||
6162 | rSt.ReadInt32( m_fcPlcftxbxBkd ); | ||||||
6163 | rSt.ReadInt32( m_lcbPlcftxbxBkd ); | ||||||
6164 | rSt.ReadInt32( m_fcPlcfHdrtxbxBkd ); | ||||||
6165 | rSt.ReadInt32( m_lcbPlcfHdrtxbxBkd ); | ||||||
6166 | if( ERRCODE_NONEErrCode(0) != rSt.GetError() ) | ||||||
6167 | { | ||||||
6168 | m_nFibError = ERR_SWG_READ_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Read, 2 ); | ||||||
6169 | } | ||||||
6170 | |||||||
6171 | rSt.Seek( 0x372 ); // fcSttbListNames | ||||||
6172 | rSt.ReadInt32( m_fcSttbListNames ); | ||||||
6173 | rSt.ReadInt32( m_lcbSttbListNames ); | ||||||
6174 | |||||||
6175 | if (m_cfclcb > 93) | ||||||
6176 | { | ||||||
6177 | rSt.Seek( 0x382 ); // MagicTables | ||||||
6178 | rSt.ReadInt32( m_fcPlcfTch ); | ||||||
6179 | rSt.ReadInt32( m_lcbPlcfTch ); | ||||||
6180 | } | ||||||
6181 | |||||||
6182 | if (m_cfclcb > 113) | ||||||
6183 | { | ||||||
6184 | rSt.Seek( 0x41A ); // new ATRD | ||||||
6185 | rSt.ReadInt32( m_fcAtrdExtra ); | ||||||
6186 | rSt.ReadUInt32( m_lcbAtrdExtra ); | ||||||
6187 | } | ||||||
6188 | |||||||
6189 | // Factoid bookmarks | ||||||
6190 | if (m_cfclcb > 134) | ||||||
6191 | { | ||||||
6192 | rSt.Seek(0x432); | ||||||
6193 | rSt.ReadInt32(m_fcPlcfBkfFactoid); | ||||||
6194 | rSt.ReadUInt32(m_lcbPlcfBkfFactoid); | ||||||
6195 | |||||||
6196 | rSt.Seek(0x442); | ||||||
6197 | rSt.ReadInt32(m_fcPlcfBklFactoid); | ||||||
6198 | rSt.ReadUInt32(m_lcbPlcfBklFactoid); | ||||||
6199 | |||||||
6200 | rSt.Seek(0x44a); | ||||||
6201 | rSt.ReadInt32(m_fcFactoidData); | ||||||
6202 | rSt.ReadUInt32(m_lcbFactoidData); | ||||||
6203 | } | ||||||
6204 | |||||||
6205 | if( ERRCODE_NONEErrCode(0) != rSt.GetError() ) | ||||||
6206 | m_nFibError = ERR_SWG_READ_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Read, 2 ); | ||||||
6207 | |||||||
6208 | rSt.Seek( 0x5bc ); // Actual nFib introduced in Word 2003 | ||||||
6209 | rSt.ReadUInt16( m_nFib_actual ); | ||||||
6210 | |||||||
6211 | rSt.Seek( nOldPos ); | ||||||
6212 | } | ||||||
6213 | } | ||||||
6214 | else | ||||||
6215 | { | ||||||
6216 | m_nFibError = ERR_SWG_READ_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Read, 2 ); // report error | ||||||
6217 | } | ||||||
6218 | } | ||||||
6219 | |||||||
6220 | WW8Fib::WW8Fib(sal_uInt8 nVer, bool bDot): | ||||||
6221 | m_nVersion(nVer), m_fDot(false), m_fGlsy(false), m_fComplex(false), m_fHasPic(false), m_cQuickSaves(0), | ||||||
6222 | m_fEncrypted(false), m_fWhichTableStm(false), m_fReadOnlyRecommended(false), | ||||||
6223 | m_fWriteReservation(false), m_fExtChar(false), m_fFarEast(false), m_fObfuscated(false), | ||||||
6224 | m_fMac(false), m_fEmptySpecial(false), m_fLoadOverridePage(false), m_fFuturesavedUndo(false), | ||||||
6225 | m_fWord97Saved(false), m_fWord2000Saved(false) | ||||||
6226 | // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the | ||||||
6227 | // above bit-field member initializations can be moved to the class definition | ||||||
6228 | { | ||||||
6229 | if (8 == nVer) | ||||||
6230 | { | ||||||
6231 | m_fcMin = 0x800; | ||||||
6232 | m_wIdent = 0xa5ec; | ||||||
6233 | m_nFib = 0x0101; | ||||||
6234 | m_nFibBack = 0xbf; | ||||||
6235 | m_nProduct = 0x204D; | ||||||
6236 | m_fDot = bDot; | ||||||
6237 | |||||||
6238 | m_csw = 0x0e; // Is this really necessary??? | ||||||
6239 | m_cfclcb = 0x88; // -""- | ||||||
6240 | m_clw = 0x16; // -""- | ||||||
6241 | m_pnFbpChpFirst = m_pnFbpPapFirst = m_pnFbpLvcFirst = 0x000fffff; | ||||||
6242 | m_fExtChar = true; | ||||||
6243 | m_fWord97Saved = m_fWord2000Saved = true; | ||||||
6244 | |||||||
6245 | // Just a fancy way to write 'Caolan80'. | ||||||
6246 | m_wMagicCreated = 0x6143; | ||||||
6247 | m_wMagicRevised = 0x6C6F; | ||||||
6248 | m_wMagicCreatedPrivate = 0x6E61; | ||||||
6249 | m_wMagicRevisedPrivate = 0x3038; | ||||||
6250 | } | ||||||
6251 | else | ||||||
6252 | { | ||||||
6253 | m_fcMin = 0x300; | ||||||
6254 | m_wIdent = 0xa5dc; | ||||||
6255 | m_nFib = m_nFibBack = 0x65; | ||||||
6256 | m_nProduct = 0xc02d; | ||||||
6257 | } | ||||||
6258 | |||||||
6259 | //If nFib is 0x00D9 or greater, then cQuickSaves MUST be 0xF | ||||||
6260 | m_cQuickSaves = m_nFib >= 0x00D9 ? 0xF : 0; | ||||||
6261 | |||||||
6262 | // --> #i90932# | ||||||
6263 | m_lid = LanguageType(0x409); // LANGUAGE_ENGLISH_US | ||||||
6264 | |||||||
6265 | LanguageType nLang = Application::GetSettings().GetLanguageTag().getLanguageType(); | ||||||
6266 | m_fFarEast = MsLangId::isCJK(nLang); | ||||||
6267 | if (m_fFarEast) | ||||||
6268 | m_lidFE = nLang; | ||||||
6269 | else | ||||||
6270 | m_lidFE = m_lid; | ||||||
6271 | |||||||
6272 | LanguageTag aLanguageTag( m_lid ); | ||||||
6273 | LocaleDataWrapper aLocaleWrapper( aLanguageTag ); | ||||||
6274 | m_nNumDecimalSep = aLocaleWrapper.getNumDecimalSep()[0]; | ||||||
6275 | } | ||||||
6276 | |||||||
6277 | |||||||
6278 | void WW8Fib::WriteHeader(SvStream& rStrm) | ||||||
6279 | { | ||||||
6280 | bool bVer8 = 8 == m_nVersion; | ||||||
6281 | |||||||
6282 | size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24; | ||||||
6283 | std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ nUnencryptedHdr ] ); | ||||||
6284 | sal_uInt8 *pData = pDataPtr.get(); | ||||||
6285 | memset( pData, 0, nUnencryptedHdr ); | ||||||
6286 | |||||||
6287 | m_cbMac = rStrm.TellEnd(); | ||||||
6288 | |||||||
6289 | Set_UInt16( pData, m_wIdent ); | ||||||
6290 | Set_UInt16( pData, m_nFib ); | ||||||
6291 | Set_UInt16( pData, m_nProduct ); | ||||||
6292 | Set_UInt16( pData, static_cast<sal_uInt16>(m_lid) ); | ||||||
6293 | Set_UInt16( pData, m_pnNext ); | ||||||
6294 | |||||||
6295 | sal_uInt16 nBits16 = 0; | ||||||
6296 | if( m_fDot ) nBits16 |= 0x0001; | ||||||
6297 | if( m_fGlsy) nBits16 |= 0x0002; | ||||||
6298 | if( m_fComplex ) nBits16 |= 0x0004; | ||||||
6299 | if( m_fHasPic ) nBits16 |= 0x0008; | ||||||
6300 | nBits16 |= (0xf0 & ( m_cQuickSaves << 4 )); | ||||||
6301 | if( m_fEncrypted ) nBits16 |= 0x0100; | ||||||
6302 | if( m_fWhichTableStm ) nBits16 |= 0x0200; | ||||||
6303 | |||||||
6304 | if (m_fReadOnlyRecommended) | ||||||
6305 | nBits16 |= 0x0400; | ||||||
6306 | if (m_fWriteReservation) | ||||||
6307 | nBits16 |= 0x0800; | ||||||
6308 | |||||||
6309 | if( m_fExtChar ) nBits16 |= 0x1000; | ||||||
6310 | if( m_fFarEast ) nBits16 |= 0x4000; // #i90932# | ||||||
6311 | if( m_fObfuscated ) nBits16 |= 0x8000; | ||||||
6312 | Set_UInt16( pData, nBits16 ); | ||||||
6313 | |||||||
6314 | Set_UInt16( pData, m_nFibBack ); | ||||||
6315 | Set_UInt16( pData, m_nHash ); | ||||||
6316 | Set_UInt16( pData, m_nKey ); | ||||||
6317 | Set_UInt8( pData, m_envr ); | ||||||
6318 | |||||||
6319 | sal_uInt8 nBits8 = 0; | ||||||
6320 | if( bVer8 ) | ||||||
6321 | { | ||||||
6322 | if( m_fMac ) nBits8 |= 0x0001; | ||||||
6323 | if( m_fEmptySpecial ) nBits8 |= 0x0002; | ||||||
6324 | if( m_fLoadOverridePage ) nBits8 |= 0x0004; | ||||||
6325 | if( m_fFuturesavedUndo ) nBits8 |= 0x0008; | ||||||
6326 | if( m_fWord97Saved ) nBits8 |= 0x0010; | ||||||
6327 | if( m_fWord2000Saved ) nBits8 |= 0x0020; | ||||||
6328 | } | ||||||
6329 | // under Ver67 these are only reserved | ||||||
6330 | Set_UInt8( pData, nBits8 ); | ||||||
6331 | |||||||
6332 | Set_UInt16( pData, m_chse ); | ||||||
6333 | Set_UInt16( pData, m_chseTables ); | ||||||
6334 | Set_UInt32( pData, m_fcMin ); | ||||||
6335 | Set_UInt32( pData, m_fcMac ); | ||||||
6336 | |||||||
6337 | // insertion for WW8 | ||||||
6338 | |||||||
6339 | // Marke: "rgsw" Beginning of the array of shorts | ||||||
6340 | if( bVer8 ) | ||||||
6341 | { | ||||||
6342 | Set_UInt16( pData, m_csw ); | ||||||
6343 | Set_UInt16( pData, m_wMagicCreated ); | ||||||
6344 | Set_UInt16( pData, m_wMagicRevised ); | ||||||
6345 | Set_UInt16( pData, m_wMagicCreatedPrivate ); | ||||||
6346 | Set_UInt16( pData, m_wMagicRevisedPrivate ); | ||||||
6347 | pData += 9 * sizeof( sal_Int16 ); | ||||||
6348 | Set_UInt16( pData, static_cast<sal_uInt16>(m_lidFE) ); | ||||||
6349 | Set_UInt16( pData, m_clw ); | ||||||
6350 | } | ||||||
6351 | |||||||
6352 | // end of the insertion for WW8 | ||||||
6353 | |||||||
6354 | // Marke: "rglw" Beginning of the array of longs | ||||||
6355 | Set_UInt32( pData, m_cbMac ); | ||||||
6356 | |||||||
6357 | rStrm.WriteBytes(pDataPtr.get(), nUnencryptedHdr); | ||||||
6358 | } | ||||||
6359 | |||||||
6360 | void WW8Fib::Write(SvStream& rStrm) | ||||||
6361 | { | ||||||
6362 | bool bVer8 = 8 == m_nVersion; | ||||||
6363 | |||||||
6364 | WriteHeader( rStrm ); | ||||||
6365 | |||||||
6366 | size_t nUnencryptedHdr = bVer8 ? 0x44 : 0x24; | ||||||
6367 | |||||||
6368 | std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ m_fcMin - nUnencryptedHdr ] ); | ||||||
6369 | sal_uInt8 *pData = pDataPtr.get(); | ||||||
6370 | memset( pData, 0, m_fcMin - nUnencryptedHdr ); | ||||||
6371 | |||||||
6372 | m_cbMac = rStrm.TellEnd(); | ||||||
6373 | |||||||
6374 | // ignore 2 longs, because they are unimportant | ||||||
6375 | pData += 2 * sizeof( sal_Int32); | ||||||
6376 | |||||||
6377 | // skipping 2 more longs only at Ver67 | ||||||
6378 | if( !bVer8 ) | ||||||
6379 | pData += 2 * sizeof( sal_Int32); | ||||||
6380 | |||||||
6381 | Set_UInt32( pData, m_ccpText ); | ||||||
6382 | Set_UInt32( pData, m_ccpFootnote ); | ||||||
6383 | Set_UInt32( pData, m_ccpHdr ); | ||||||
6384 | Set_UInt32( pData, m_ccpMcr ); | ||||||
6385 | Set_UInt32( pData, m_ccpAtn ); | ||||||
6386 | Set_UInt32( pData, m_ccpEdn ); | ||||||
6387 | Set_UInt32( pData, m_ccpTxbx ); | ||||||
6388 | Set_UInt32( pData, m_ccpHdrTxbx ); | ||||||
6389 | |||||||
6390 | // only skip one more long at Ver67 | ||||||
6391 | if( !bVer8 ) | ||||||
6392 | pData += 1 * sizeof( sal_Int32); | ||||||
6393 | |||||||
6394 | // insertion for WW8 | ||||||
6395 | if( bVer8 ) | ||||||
6396 | { | ||||||
6397 | Set_UInt32( pData, m_pnFbpChpFirst ); | ||||||
6398 | Set_UInt32( pData, m_pnChpFirst ); | ||||||
6399 | Set_UInt32( pData, m_cpnBteChp ); | ||||||
6400 | Set_UInt32( pData, m_pnFbpPapFirst ); | ||||||
6401 | Set_UInt32( pData, m_pnPapFirst ); | ||||||
6402 | Set_UInt32( pData, m_cpnBtePap ); | ||||||
6403 | Set_UInt32( pData, m_pnFbpLvcFirst ); | ||||||
6404 | Set_UInt32( pData, m_pnLvcFirst ); | ||||||
6405 | Set_UInt32( pData, m_cpnBteLvc ); | ||||||
6406 | Set_UInt32( pData, m_fcIslandFirst ); | ||||||
6407 | Set_UInt32( pData, m_fcIslandLim ); | ||||||
6408 | Set_UInt16( pData, m_cfclcb ); | ||||||
6409 | } | ||||||
6410 | // end of the insertion for WW8 | ||||||
6411 | |||||||
6412 | // Marke: "rgfclcb" Beginning of array of FC/LCB pairs. | ||||||
6413 | Set_UInt32( pData, m_fcStshfOrig ); | ||||||
6414 | Set_UInt32( pData, m_lcbStshfOrig ); | ||||||
6415 | Set_UInt32( pData, m_fcStshf ); | ||||||
6416 | Set_UInt32( pData, m_lcbStshf ); | ||||||
6417 | Set_UInt32( pData, m_fcPlcffndRef ); | ||||||
6418 | Set_UInt32( pData, m_lcbPlcffndRef ); | ||||||
6419 | Set_UInt32( pData, m_fcPlcffndText ); | ||||||
6420 | Set_UInt32( pData, m_lcbPlcffndText ); | ||||||
6421 | Set_UInt32( pData, m_fcPlcfandRef ); | ||||||
6422 | Set_UInt32( pData, m_lcbPlcfandRef ); | ||||||
6423 | Set_UInt32( pData, m_fcPlcfandText ); | ||||||
6424 | Set_UInt32( pData, m_lcbPlcfandText ); | ||||||
6425 | Set_UInt32( pData, m_fcPlcfsed ); | ||||||
6426 | Set_UInt32( pData, m_lcbPlcfsed ); | ||||||
6427 | Set_UInt32( pData, m_fcPlcfpad ); | ||||||
6428 | Set_UInt32( pData, m_lcbPlcfpad ); | ||||||
6429 | Set_UInt32( pData, m_fcPlcfphe ); | ||||||
6430 | Set_UInt32( pData, m_lcbPlcfphe ); | ||||||
6431 | Set_UInt32( pData, m_fcSttbfglsy ); | ||||||
6432 | Set_UInt32( pData, m_lcbSttbfglsy ); | ||||||
6433 | Set_UInt32( pData, m_fcPlcfglsy ); | ||||||
6434 | Set_UInt32( pData, m_lcbPlcfglsy ); | ||||||
6435 | Set_UInt32( pData, m_fcPlcfhdd ); | ||||||
6436 | Set_UInt32( pData, m_lcbPlcfhdd ); | ||||||
6437 | Set_UInt32( pData, m_fcPlcfbteChpx ); | ||||||
6438 | Set_UInt32( pData, m_lcbPlcfbteChpx ); | ||||||
6439 | Set_UInt32( pData, m_fcPlcfbtePapx ); | ||||||
6440 | Set_UInt32( pData, m_lcbPlcfbtePapx ); | ||||||
6441 | Set_UInt32( pData, m_fcPlcfsea ); | ||||||
6442 | Set_UInt32( pData, m_lcbPlcfsea ); | ||||||
6443 | Set_UInt32( pData, m_fcSttbfffn ); | ||||||
6444 | Set_UInt32( pData, m_lcbSttbfffn ); | ||||||
6445 | Set_UInt32( pData, m_fcPlcffldMom ); | ||||||
6446 | Set_UInt32( pData, m_lcbPlcffldMom ); | ||||||
6447 | Set_UInt32( pData, m_fcPlcffldHdr ); | ||||||
6448 | Set_UInt32( pData, m_lcbPlcffldHdr ); | ||||||
6449 | Set_UInt32( pData, m_fcPlcffldFootnote ); | ||||||
6450 | Set_UInt32( pData, m_lcbPlcffldFootnote ); | ||||||
6451 | Set_UInt32( pData, m_fcPlcffldAtn ); | ||||||
6452 | Set_UInt32( pData, m_lcbPlcffldAtn ); | ||||||
6453 | Set_UInt32( pData, m_fcPlcffldMcr ); | ||||||
6454 | Set_UInt32( pData, m_lcbPlcffldMcr ); | ||||||
6455 | Set_UInt32( pData, m_fcSttbfbkmk ); | ||||||
6456 | Set_UInt32( pData, m_lcbSttbfbkmk ); | ||||||
6457 | Set_UInt32( pData, m_fcPlcfbkf ); | ||||||
6458 | Set_UInt32( pData, m_lcbPlcfbkf ); | ||||||
6459 | Set_UInt32( pData, m_fcPlcfbkl ); | ||||||
6460 | Set_UInt32( pData, m_lcbPlcfbkl ); | ||||||
6461 | Set_UInt32( pData, m_fcCmds ); | ||||||
6462 | Set_UInt32( pData, m_lcbCmds ); | ||||||
6463 | Set_UInt32( pData, m_fcPlcfmcr ); | ||||||
6464 | Set_UInt32( pData, m_lcbPlcfmcr ); | ||||||
6465 | Set_UInt32( pData, m_fcSttbfmcr ); | ||||||
6466 | Set_UInt32( pData, m_lcbSttbfmcr ); | ||||||
6467 | Set_UInt32( pData, m_fcPrDrvr ); | ||||||
6468 | Set_UInt32( pData, m_lcbPrDrvr ); | ||||||
6469 | Set_UInt32( pData, m_fcPrEnvPort ); | ||||||
6470 | Set_UInt32( pData, m_lcbPrEnvPort ); | ||||||
6471 | Set_UInt32( pData, m_fcPrEnvLand ); | ||||||
6472 | Set_UInt32( pData, m_lcbPrEnvLand ); | ||||||
6473 | Set_UInt32( pData, m_fcWss ); | ||||||
6474 | Set_UInt32( pData, m_lcbWss ); | ||||||
6475 | Set_UInt32( pData, m_fcDop ); | ||||||
6476 | Set_UInt32( pData, m_lcbDop ); | ||||||
6477 | Set_UInt32( pData, m_fcSttbfAssoc ); | ||||||
6478 | Set_UInt32( pData, m_lcbSttbfAssoc ); | ||||||
6479 | Set_UInt32( pData, m_fcClx ); | ||||||
6480 | Set_UInt32( pData, m_lcbClx ); | ||||||
6481 | Set_UInt32( pData, m_fcPlcfpgdFootnote ); | ||||||
6482 | Set_UInt32( pData, m_lcbPlcfpgdFootnote ); | ||||||
6483 | Set_UInt32( pData, m_fcAutosaveSource ); | ||||||
6484 | Set_UInt32( pData, m_lcbAutosaveSource ); | ||||||
6485 | Set_UInt32( pData, m_fcGrpStAtnOwners ); | ||||||
6486 | Set_UInt32( pData, m_lcbGrpStAtnOwners ); | ||||||
6487 | Set_UInt32( pData, m_fcSttbfAtnbkmk ); | ||||||
6488 | Set_UInt32( pData, m_lcbSttbfAtnbkmk ); | ||||||
6489 | |||||||
6490 | // only skip one more short at Ver67 | ||||||
6491 | if( !bVer8 ) | ||||||
6492 | { | ||||||
6493 | pData += 1*sizeof( sal_Int16); | ||||||
6494 | Set_UInt16( pData, static_cast<sal_uInt16>(m_pnChpFirst) ); | ||||||
6495 | Set_UInt16( pData, static_cast<sal_uInt16>(m_pnPapFirst) ); | ||||||
6496 | Set_UInt16( pData, static_cast<sal_uInt16>(m_cpnBteChp) ); | ||||||
6497 | Set_UInt16( pData, static_cast<sal_uInt16>(m_cpnBtePap) ); | ||||||
6498 | } | ||||||
6499 | |||||||
6500 | Set_UInt32( pData, m_fcPlcfdoaMom ); // only at Ver67, in Ver8 unused | ||||||
6501 | Set_UInt32( pData, m_lcbPlcfdoaMom ); // only at Ver67, in Ver8 unused | ||||||
6502 | Set_UInt32( pData, m_fcPlcfdoaHdr ); // only at Ver67, in Ver8 unused | ||||||
6503 | Set_UInt32( pData, m_lcbPlcfdoaHdr ); // only at Ver67, in Ver8 unused | ||||||
6504 | |||||||
6505 | Set_UInt32( pData, m_fcPlcfspaMom ); // in Ver67 empty reserve | ||||||
6506 | Set_UInt32( pData, m_lcbPlcfspaMom ); // in Ver67 empty reserve | ||||||
6507 | Set_UInt32( pData, m_fcPlcfspaHdr ); // in Ver67 empty reserve | ||||||
6508 | Set_UInt32( pData, m_lcbPlcfspaHdr ); // in Ver67 empty reserve | ||||||
6509 | |||||||
6510 | Set_UInt32( pData, m_fcPlcfAtnbkf ); | ||||||
6511 | Set_UInt32( pData, m_lcbPlcfAtnbkf ); | ||||||
6512 | Set_UInt32( pData, m_fcPlcfAtnbkl ); | ||||||
6513 | Set_UInt32( pData, m_lcbPlcfAtnbkl ); | ||||||
6514 | Set_UInt32( pData, m_fcPms ); | ||||||
6515 | Set_UInt32( pData, m_lcbPMS ); | ||||||
6516 | Set_UInt32( pData, m_fcFormFieldSttbf ); | ||||||
6517 | Set_UInt32( pData, m_lcbFormFieldSttbf ); | ||||||
6518 | Set_UInt32( pData, m_fcPlcfendRef ); | ||||||
6519 | Set_UInt32( pData, m_lcbPlcfendRef ); | ||||||
6520 | Set_UInt32( pData, m_fcPlcfendText ); | ||||||
6521 | Set_UInt32( pData, m_lcbPlcfendText ); | ||||||
6522 | Set_UInt32( pData, m_fcPlcffldEdn ); | ||||||
6523 | Set_UInt32( pData, m_lcbPlcffldEdn ); | ||||||
6524 | Set_UInt32( pData, m_fcPlcfpgdEdn ); | ||||||
6525 | Set_UInt32( pData, m_lcbPlcfpgdEdn ); | ||||||
6526 | Set_UInt32( pData, m_fcDggInfo ); // in Ver67 empty reserve | ||||||
6527 | Set_UInt32( pData, m_lcbDggInfo ); // in Ver67 empty reserve | ||||||
6528 | Set_UInt32( pData, m_fcSttbfRMark ); | ||||||
6529 | Set_UInt32( pData, m_lcbSttbfRMark ); | ||||||
6530 | Set_UInt32( pData, m_fcSttbfCaption ); | ||||||
6531 | Set_UInt32( pData, m_lcbSttbfCaption ); | ||||||
6532 | Set_UInt32( pData, m_fcSttbAutoCaption ); | ||||||
6533 | Set_UInt32( pData, m_lcbSttbAutoCaption ); | ||||||
6534 | Set_UInt32( pData, m_fcPlcfwkb ); | ||||||
6535 | Set_UInt32( pData, m_lcbPlcfwkb ); | ||||||
6536 | Set_UInt32( pData, m_fcPlcfspl ); // in Ver67 empty reserve | ||||||
6537 | Set_UInt32( pData, m_lcbPlcfspl ); // in Ver67 empty reserve | ||||||
6538 | Set_UInt32( pData, m_fcPlcftxbxText ); | ||||||
6539 | Set_UInt32( pData, m_lcbPlcftxbxText ); | ||||||
6540 | Set_UInt32( pData, m_fcPlcffldTxbx ); | ||||||
6541 | Set_UInt32( pData, m_lcbPlcffldTxbx ); | ||||||
6542 | Set_UInt32( pData, m_fcPlcfHdrtxbxText ); | ||||||
6543 | Set_UInt32( pData, m_lcbPlcfHdrtxbxText ); | ||||||
6544 | Set_UInt32( pData, m_fcPlcffldHdrTxbx ); | ||||||
6545 | Set_UInt32( pData, m_lcbPlcffldHdrTxbx ); | ||||||
6546 | |||||||
6547 | if( bVer8 ) | ||||||
6548 | { | ||||||
6549 | pData += 0x2da - 0x27a; // Pos + Offset (fcPlcfLst - fcStwUser) | ||||||
6550 | Set_UInt32( pData, m_fcSttbFnm); | ||||||
6551 | Set_UInt32( pData, m_lcbSttbFnm); | ||||||
6552 | Set_UInt32( pData, m_fcPlcfLst ); | ||||||
6553 | Set_UInt32( pData, m_lcbPlcfLst ); | ||||||
6554 | Set_UInt32( pData, m_fcPlfLfo ); | ||||||
6555 | Set_UInt32( pData, m_lcbPlfLfo ); | ||||||
6556 | Set_UInt32( pData, m_fcPlcftxbxBkd ); | ||||||
6557 | Set_UInt32( pData, m_lcbPlcftxbxBkd ); | ||||||
6558 | Set_UInt32( pData, m_fcPlcfHdrtxbxBkd ); | ||||||
6559 | Set_UInt32( pData, m_lcbPlcfHdrtxbxBkd ); | ||||||
6560 | |||||||
6561 | pData += 0x372 - 0x302; // Pos + Offset (fcSttbListNames - fcDocUndo) | ||||||
6562 | Set_UInt32( pData, m_fcSttbListNames ); | ||||||
6563 | Set_UInt32( pData, m_lcbSttbListNames ); | ||||||
6564 | |||||||
6565 | pData += 0x382 - 0x37A; | ||||||
6566 | Set_UInt32( pData, m_fcPlcfTch ); | ||||||
6567 | Set_UInt32( pData, m_lcbPlcfTch ); | ||||||
6568 | |||||||
6569 | pData += 0x3FA - 0x38A; | ||||||
6570 | Set_UInt16( pData, sal_uInt16(0x0002)); | ||||||
6571 | Set_UInt16( pData, sal_uInt16(0x00D9)); | ||||||
6572 | |||||||
6573 | pData += 0x41A - 0x3FE; | ||||||
6574 | Set_UInt32( pData, m_fcAtrdExtra ); | ||||||
6575 | Set_UInt32( pData, m_lcbAtrdExtra ); | ||||||
6576 | |||||||
6577 | pData += 0x42a - 0x422; | ||||||
6578 | Set_UInt32(pData, m_fcSttbfBkmkFactoid); | ||||||
6579 | Set_UInt32(pData, m_lcbSttbfBkmkFactoid); | ||||||
6580 | Set_UInt32(pData, m_fcPlcfBkfFactoid); | ||||||
6581 | Set_UInt32(pData, m_lcbPlcfBkfFactoid); | ||||||
6582 | |||||||
6583 | pData += 0x442 - 0x43A; | ||||||
6584 | Set_UInt32(pData, m_fcPlcfBklFactoid); | ||||||
6585 | Set_UInt32(pData, m_lcbPlcfBklFactoid); | ||||||
6586 | Set_UInt32(pData, m_fcFactoidData); | ||||||
6587 | Set_UInt32(pData, m_lcbFactoidData); | ||||||
6588 | |||||||
6589 | pData += 0x4BA - 0x452; | ||||||
6590 | Set_UInt32(pData, m_fcPlcffactoid); | ||||||
6591 | Set_UInt32(pData, m_lcbPlcffactoid); | ||||||
6592 | |||||||
6593 | pData += 0x4DA - 0x4c2; | ||||||
6594 | Set_UInt32( pData, m_fcHplxsdr ); | ||||||
6595 | Set_UInt32( pData, 0); | ||||||
6596 | } | ||||||
6597 | |||||||
6598 | rStrm.WriteBytes(pDataPtr.get(), m_fcMin - nUnencryptedHdr); | ||||||
6599 | } | ||||||
6600 | |||||||
6601 | rtl_TextEncoding WW8Fib::GetFIBCharset(sal_uInt16 chs, LanguageType nLidLocale) | ||||||
6602 | { | ||||||
6603 | OSL_ENSURE(chs <= 0x100, "overflowed winword charset set")do { if (true && (!(chs <= 0x100))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6603" ": "), "%s", "overflowed winword charset set"); } } while (false); | ||||||
6604 | if (chs == 0x0100) | ||||||
6605 | return RTL_TEXTENCODING_APPLE_ROMAN(((rtl_TextEncoding) 2)); | ||||||
6606 | if (chs == 0 && static_cast<sal_uInt16>(nLidLocale) >= 999) | ||||||
6607 | { | ||||||
6608 | /* | ||||||
6609 | nLidLocale: | ||||||
6610 | language stamp -- localized version In pre-WinWord 2.0 files this | ||||||
6611 | value was the nLocale. If value is < 999, then it is the nLocale, | ||||||
6612 | otherwise it is the lid. | ||||||
6613 | */ | ||||||
6614 | css::lang::Locale aLocale(LanguageTag::convertToLocale(nLidLocale)); | ||||||
6615 | return msfilter::util::getBestTextEncodingFromLocale(aLocale); | ||||||
6616 | } | ||||||
6617 | return rtl_getTextEncodingFromWindowsCharset(static_cast<sal_uInt8>(chs)); | ||||||
6618 | } | ||||||
6619 | |||||||
6620 | MSOFactoidType::MSOFactoidType() | ||||||
6621 | : m_nId(0) | ||||||
6622 | { | ||||||
6623 | } | ||||||
6624 | |||||||
6625 | namespace MSOPBString | ||||||
6626 | { | ||||||
6627 | static OUString Read(SvStream& rStream) | ||||||
6628 | { | ||||||
6629 | OUString aRet; | ||||||
6630 | |||||||
6631 | sal_uInt16 nBuf(0); | ||||||
6632 | rStream.ReadUInt16(nBuf); | ||||||
6633 | sal_uInt16 nCch = nBuf & 0x7fff; // Bits 1..15. | ||||||
6634 | bool bAnsiString = (nBuf & (1 << 15)) >> 15; // 16th bit. | ||||||
6635 | if (bAnsiString) | ||||||
6636 | aRet = OStringToOUString(read_uInt8s_ToOString(rStream, nCch), RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))); | ||||||
6637 | else | ||||||
6638 | aRet = read_uInt16s_ToOUString(rStream, nCch); | ||||||
6639 | |||||||
6640 | return aRet; | ||||||
6641 | } | ||||||
6642 | |||||||
6643 | static void Write(const OUString& rString, SvStream& rStream) | ||||||
6644 | { | ||||||
6645 | sal_uInt16 nBuf = 0; | ||||||
6646 | nBuf |= rString.getLength(); // cch, 0..14th bits. | ||||||
6647 | nBuf |= 0x8000; // fAnsiString, 15th bit. | ||||||
6648 | rStream.WriteUInt16(nBuf); | ||||||
6649 | SwWW8Writer::WriteString8(rStream, rString, false, RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11))); | ||||||
6650 | } | ||||||
6651 | }; | ||||||
6652 | |||||||
6653 | void MSOFactoidType::Read(SvStream& rStream) | ||||||
6654 | { | ||||||
6655 | sal_uInt32 cbFactoid(0); | ||||||
6656 | rStream.ReadUInt32(cbFactoid); | ||||||
6657 | rStream.ReadUInt32(m_nId); | ||||||
6658 | m_aUri = MSOPBString::Read(rStream); | ||||||
6659 | m_aTag = MSOPBString::Read(rStream); | ||||||
6660 | MSOPBString::Read(rStream); // rgbDownloadURL | ||||||
6661 | } | ||||||
6662 | |||||||
6663 | void MSOFactoidType::Write(WW8Export& rExport) | ||||||
6664 | { | ||||||
6665 | SvStream& rStream = *rExport.pTableStrm; | ||||||
6666 | |||||||
6667 | SvMemoryStream aStream; | ||||||
6668 | aStream.WriteUInt32(m_nId); // id | ||||||
6669 | MSOPBString::Write(m_aUri, aStream); | ||||||
6670 | MSOPBString::Write(m_aTag, aStream); | ||||||
6671 | MSOPBString::Write("", aStream); // rgbDownloadURL | ||||||
6672 | rStream.WriteUInt32(aStream.Tell()); | ||||||
6673 | aStream.Seek(0); | ||||||
6674 | rStream.WriteStream(aStream); | ||||||
6675 | } | ||||||
6676 | |||||||
6677 | void MSOPropertyBagStore::Read(SvStream& rStream) | ||||||
6678 | { | ||||||
6679 | sal_uInt32 cFactoidType(0); | ||||||
6680 | rStream.ReadUInt32(cFactoidType); | ||||||
6681 | for (sal_uInt32 i = 0; i < cFactoidType && rStream.good(); ++i) | ||||||
6682 | { | ||||||
6683 | MSOFactoidType aFactoidType; | ||||||
6684 | aFactoidType.Read(rStream); | ||||||
6685 | m_aFactoidTypes.push_back(aFactoidType); | ||||||
6686 | } | ||||||
6687 | sal_uInt16 cbHdr(0); | ||||||
6688 | rStream.ReadUInt16(cbHdr); | ||||||
6689 | SAL_WARN_IF(cbHdr != 0xc, "sw.ww8", "MSOPropertyBagStore::Read: unexpected cbHdr")do { if (true && (cbHdr != 0xc)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "MSOPropertyBagStore::Read: unexpected cbHdr" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6689" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "MSOPropertyBagStore::Read: unexpected cbHdr" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "MSOPropertyBagStore::Read: unexpected cbHdr"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6689" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "MSOPropertyBagStore::Read: unexpected cbHdr") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6689" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "MSOPropertyBagStore::Read: unexpected cbHdr" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "MSOPropertyBagStore::Read: unexpected cbHdr"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6689" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
6690 | sal_uInt16 nVer(0); | ||||||
6691 | rStream.ReadUInt16(nVer); | ||||||
6692 | SAL_WARN_IF(nVer != 0x0100, "sw.ww8", "MSOPropertyBagStore::Read: unexpected nVer")do { if (true && (nVer != 0x0100)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "MSOPropertyBagStore::Read: unexpected nVer" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6692" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "MSOPropertyBagStore::Read: unexpected nVer" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "MSOPropertyBagStore::Read: unexpected nVer"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6692" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "MSOPropertyBagStore::Read: unexpected nVer") == 1 ) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6692" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "MSOPropertyBagStore::Read: unexpected nVer" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "MSOPropertyBagStore::Read: unexpected nVer"; ::sal ::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6692" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
6693 | rStream.SeekRel(4); // cfactoid | ||||||
6694 | sal_uInt32 nCste(0); | ||||||
6695 | rStream.ReadUInt32(nCste); | ||||||
6696 | |||||||
6697 | //each string has a 2 byte len record at the start | ||||||
6698 | const size_t nMaxPossibleRecords = rStream.remainingSize() / sizeof(sal_uInt16); | ||||||
6699 | if (nCste > nMaxPossibleRecords) | ||||||
6700 | { | ||||||
6701 | SAL_WARN("sw.ww8", nCste << " records claimed, but max possible is " << nMaxPossibleRecords)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << nCste << " records claimed, but max possible is " << nMaxPossibleRecords) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6701" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << nCste << " records claimed, but max possible is " << nMaxPossibleRecords), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << nCste << " records claimed, but max possible is " << nMaxPossibleRecords ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6701" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << nCste << " records claimed, but max possible is " << nMaxPossibleRecords) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6701" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << nCste << " records claimed, but max possible is " << nMaxPossibleRecords), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << nCste << " records claimed, but max possible is " << nMaxPossibleRecords ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6701" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
6702 | nCste = nMaxPossibleRecords; | ||||||
6703 | } | ||||||
6704 | |||||||
6705 | for (sal_uInt32 i = 0; i < nCste; ++i) | ||||||
6706 | { | ||||||
6707 | OUString aString = MSOPBString::Read(rStream); | ||||||
6708 | m_aStringTable.push_back(aString); | ||||||
6709 | } | ||||||
6710 | } | ||||||
6711 | |||||||
6712 | void MSOPropertyBagStore::Write(WW8Export& rExport) | ||||||
6713 | { | ||||||
6714 | SvStream& rStream = *rExport.pTableStrm; | ||||||
6715 | rStream.WriteUInt32(m_aFactoidTypes.size()); // cFactoidType | ||||||
6716 | for (MSOFactoidType& rType : m_aFactoidTypes) | ||||||
6717 | rType.Write(rExport); | ||||||
6718 | rStream.WriteUInt16(0xc); // cbHdr | ||||||
6719 | rStream.WriteUInt16(0x0100); // sVer | ||||||
6720 | rStream.WriteUInt32(0); // cfactoid | ||||||
6721 | rStream.WriteUInt32(m_aStringTable.size()); // cste | ||||||
6722 | for (const OUString& rString : m_aStringTable) | ||||||
6723 | MSOPBString::Write(rString, rStream); | ||||||
6724 | } | ||||||
6725 | |||||||
6726 | MSOProperty::MSOProperty() | ||||||
6727 | : m_nKey(0) | ||||||
6728 | , m_nValue(0) | ||||||
6729 | { | ||||||
6730 | } | ||||||
6731 | |||||||
6732 | void MSOProperty::Read(SvStream& rStream) | ||||||
6733 | { | ||||||
6734 | rStream.ReadUInt32(m_nKey); | ||||||
6735 | rStream.ReadUInt32(m_nValue); | ||||||
6736 | } | ||||||
6737 | |||||||
6738 | void MSOProperty::Write(SvStream& rStream) | ||||||
6739 | { | ||||||
6740 | rStream.WriteUInt32(m_nKey); | ||||||
6741 | rStream.WriteUInt32(m_nValue); | ||||||
6742 | } | ||||||
6743 | |||||||
6744 | MSOPropertyBag::MSOPropertyBag() | ||||||
6745 | : m_nId(0) | ||||||
6746 | { | ||||||
6747 | } | ||||||
6748 | |||||||
6749 | bool MSOPropertyBag::Read(SvStream& rStream) | ||||||
6750 | { | ||||||
6751 | rStream.ReadUInt16(m_nId); | ||||||
6752 | sal_uInt16 cProp(0); | ||||||
6753 | rStream.ReadUInt16(cProp); | ||||||
6754 | if (!rStream.good()) | ||||||
6755 | return false; | ||||||
6756 | rStream.SeekRel(2); // cbUnknown | ||||||
6757 | //each MSOProperty is 8 bytes in size | ||||||
6758 | const size_t nMaxPossibleRecords = rStream.remainingSize() / 8; | ||||||
6759 | if (cProp > nMaxPossibleRecords) | ||||||
6760 | { | ||||||
6761 | SAL_WARN("sw.ww8", cProp << " records claimed, but max possible is " << nMaxPossibleRecords)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << cProp << " records claimed, but max possible is " << nMaxPossibleRecords) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6761" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << cProp << " records claimed, but max possible is " << nMaxPossibleRecords), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << cProp << " records claimed, but max possible is " << nMaxPossibleRecords ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6761" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << cProp << " records claimed, but max possible is " << nMaxPossibleRecords) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6761" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << cProp << " records claimed, but max possible is " << nMaxPossibleRecords), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << cProp << " records claimed, but max possible is " << nMaxPossibleRecords ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6761" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
6762 | cProp = nMaxPossibleRecords; | ||||||
6763 | } | ||||||
6764 | for (sal_uInt16 i = 0; i < cProp && rStream.good(); ++i) | ||||||
6765 | { | ||||||
6766 | MSOProperty aProperty; | ||||||
6767 | aProperty.Read(rStream); | ||||||
6768 | m_aProperties.push_back(aProperty); | ||||||
6769 | } | ||||||
6770 | return rStream.good(); | ||||||
6771 | } | ||||||
6772 | |||||||
6773 | void MSOPropertyBag::Write(WW8Export& rExport) | ||||||
6774 | { | ||||||
6775 | SvStream& rStream = *rExport.pTableStrm; | ||||||
6776 | rStream.WriteUInt16(m_nId); | ||||||
6777 | rStream.WriteUInt16(m_aProperties.size()); | ||||||
6778 | rStream.WriteUInt16(0); // cbUnknown | ||||||
6779 | for (MSOProperty& rProperty : m_aProperties) | ||||||
6780 | rProperty.Write(rStream); | ||||||
6781 | } | ||||||
6782 | |||||||
6783 | void WW8SmartTagData::Read(SvStream& rStream, WW8_FC fcFactoidData, sal_uInt32 lcbFactoidData) | ||||||
6784 | { | ||||||
6785 | sal_uInt64 nOldPosition = rStream.Tell(); | ||||||
6786 | if (!checkSeek(rStream, fcFactoidData)) | ||||||
6787 | return; | ||||||
6788 | |||||||
6789 | m_aPropBagStore.Read(rStream); | ||||||
6790 | while (rStream.good() && rStream.Tell() < fcFactoidData + lcbFactoidData) | ||||||
6791 | { | ||||||
6792 | MSOPropertyBag aPropertyBag; | ||||||
6793 | if (!aPropertyBag.Read(rStream)) | ||||||
6794 | break; | ||||||
6795 | m_aPropBags.push_back(aPropertyBag); | ||||||
6796 | } | ||||||
6797 | |||||||
6798 | rStream.Seek(nOldPosition); | ||||||
6799 | } | ||||||
6800 | |||||||
6801 | void WW8SmartTagData::Write(WW8Export& rExport) | ||||||
6802 | { | ||||||
6803 | m_aPropBagStore.Write(rExport); | ||||||
6804 | for (MSOPropertyBag& rPropertyBag : m_aPropBags) | ||||||
6805 | rPropertyBag.Write(rExport); | ||||||
6806 | } | ||||||
6807 | |||||||
6808 | WW8Style::WW8Style(SvStream& rStream, WW8Fib& rFibPara) | ||||||
6809 | : m_rFib(rFibPara), m_rStream(rStream), m_cstd(0), m_cbSTDBaseInFile(0), m_fStdStylenamesWritten(0) | ||||||
6810 | , m_stiMaxWhenSaved(0), m_istdMaxFixedWhenSaved(0), m_nVerBuiltInNamesWhenSaved(0) | ||||||
6811 | , m_ftcAsci(0), m_ftcFE(0), m_ftcOther(0), m_ftcBi(0) | ||||||
6812 | { | ||||||
6813 | if (!checkSeek(m_rStream, m_rFib.m_fcStshf)) | ||||||
6814 | return; | ||||||
6815 | |||||||
6816 | sal_uInt16 cbStshi = 0; // 2 bytes size of the following STSHI structure | ||||||
6817 | sal_uInt32 nRemaining = m_rFib.m_lcbStshf; | ||||||
6818 | const sal_uInt32 nMinValidStshi = 4; | ||||||
6819 | |||||||
6820 | if (m_rFib.GetFIBVersion() <= ww::eWW2) | ||||||
6821 | { | ||||||
6822 | cbStshi = 0; | ||||||
6823 | m_cstd = 256; | ||||||
6824 | } | ||||||
6825 | else | ||||||
6826 | { | ||||||
6827 | if (m_rFib.m_nFib < 67) // old Version ? (need to find this again to fix) | ||||||
6828 | cbStshi = nMinValidStshi; | ||||||
6829 | else // new version | ||||||
6830 | { | ||||||
6831 | if (nRemaining < sizeof(cbStshi)) | ||||||
6832 | return; | ||||||
6833 | // reads the length of the structure in the file | ||||||
6834 | m_rStream.ReadUInt16( cbStshi ); | ||||||
6835 | nRemaining-=2; | ||||||
6836 | } | ||||||
6837 | } | ||||||
6838 | |||||||
6839 | cbStshi = std::min(static_cast<sal_uInt32>(cbStshi), nRemaining); | ||||||
6840 | if (cbStshi < nMinValidStshi) | ||||||
6841 | return; | ||||||
6842 | |||||||
6843 | const sal_uInt16 nRead = cbStshi; | ||||||
6844 | do | ||||||
6845 | { | ||||||
6846 | m_rStream.ReadUInt16( m_cstd ); | ||||||
6847 | |||||||
6848 | m_rStream.ReadUInt16( m_cbSTDBaseInFile ); | ||||||
6849 | |||||||
6850 | if( 6 > nRead ) break; | ||||||
6851 | |||||||
6852 | sal_uInt16 a16Bit; | ||||||
6853 | m_rStream.ReadUInt16( a16Bit ); | ||||||
6854 | m_fStdStylenamesWritten = a16Bit & 0x0001; | ||||||
6855 | |||||||
6856 | if( 8 > nRead ) break; | ||||||
6857 | m_rStream.ReadUInt16( m_stiMaxWhenSaved ); | ||||||
6858 | |||||||
6859 | if( 10 > nRead ) break; | ||||||
6860 | m_rStream.ReadUInt16( m_istdMaxFixedWhenSaved ); | ||||||
6861 | |||||||
6862 | if( 12 > nRead ) break; | ||||||
6863 | m_rStream.ReadUInt16( m_nVerBuiltInNamesWhenSaved ); | ||||||
6864 | |||||||
6865 | if( 14 > nRead ) break; | ||||||
6866 | m_rStream.ReadUInt16( m_ftcAsci ); | ||||||
6867 | |||||||
6868 | if( 16 > nRead ) break; | ||||||
6869 | m_rStream.ReadUInt16( m_ftcFE ); | ||||||
6870 | |||||||
6871 | if ( 18 > nRead ) break; | ||||||
6872 | m_rStream.ReadUInt16( m_ftcOther ); | ||||||
6873 | |||||||
6874 | m_ftcBi = m_ftcOther; | ||||||
6875 | |||||||
6876 | if ( 20 > nRead ) break; | ||||||
6877 | m_rStream.ReadUInt16( m_ftcBi ); | ||||||
6878 | |||||||
6879 | // p.r.n. ignore the rest | ||||||
6880 | if( 20 < nRead ) | ||||||
6881 | m_rStream.SeekRel( nRead-20 ); | ||||||
6882 | } | ||||||
6883 | while( false ); // trick: the block above will be passed through exactly one time | ||||||
6884 | // and that's why we can early exit with "break". | ||||||
6885 | |||||||
6886 | nRemaining -= cbStshi; | ||||||
6887 | |||||||
6888 | //There will be stshi.cstd (cbSTD, STD) pairs in the file following the | ||||||
6889 | //STSHI. Note that styles can be empty, i.e. cbSTD == 0 | ||||||
6890 | const sal_uInt32 nMinRecordSize = sizeof(sal_uInt16); | ||||||
6891 | const sal_uInt16 nMaxPossibleRecords = nRemaining/nMinRecordSize; | ||||||
6892 | |||||||
6893 | OSL_ENSURE(m_cstd <= nMaxPossibleRecords,do { if (true && (!(m_cstd <= nMaxPossibleRecords) )) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6894" ": "), "%s", "allegedly more styles that available data" ); } } while (false) | ||||||
6894 | "allegedly more styles that available data")do { if (true && (!(m_cstd <= nMaxPossibleRecords) )) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "6894" ": "), "%s", "allegedly more styles that available data" ); } } while (false); | ||||||
6895 | m_cstd = std::min(m_cstd, nMaxPossibleRecords); | ||||||
6896 | } | ||||||
6897 | |||||||
6898 | // Read1STDFixed() reads a style. If the style is completely existent, | ||||||
6899 | // so it has no empty slot, we should allocate memory and a pointer should | ||||||
6900 | // reference to STD (perhaps filled with 0). If the slot is empty, | ||||||
6901 | // it will return a null pointer. | ||||||
6902 | std::unique_ptr<WW8_STD> WW8Style::Read1STDFixed(sal_uInt16& rSkip) | ||||||
6903 | { | ||||||
6904 | std::unique_ptr<WW8_STD> pStd; | ||||||
6905 | |||||||
6906 | sal_uInt16 cbStd(0); | ||||||
6907 | m_rStream.ReadUInt16(cbStd); // read length | ||||||
6908 | |||||||
6909 | const sal_uInt16 nRead = m_cbSTDBaseInFile; | ||||||
6910 | if( cbStd >= m_cbSTDBaseInFile ) | ||||||
6911 | { | ||||||
6912 | // Fixed part completely available | ||||||
6913 | |||||||
6914 | // read fixed part of STD | ||||||
6915 | pStd.reset(new WW8_STD); | ||||||
6916 | memset( pStd.get(), 0, sizeof( *pStd ) ); | ||||||
6917 | |||||||
6918 | do | ||||||
6919 | { | ||||||
6920 | if( 2 > nRead ) break; | ||||||
6921 | |||||||
6922 | sal_uInt16 a16Bit = 0; | ||||||
6923 | m_rStream.ReadUInt16( a16Bit ); | ||||||
6924 | pStd->sti = a16Bit & 0x0fff ; | ||||||
6925 | pStd->fScratch = sal_uInt16(0 != ( a16Bit & 0x1000 )); | ||||||
6926 | pStd->fInvalHeight = sal_uInt16(0 != ( a16Bit & 0x2000 )); | ||||||
6927 | pStd->fHasUpe = sal_uInt16(0 != ( a16Bit & 0x4000 )); | ||||||
6928 | pStd->fMassCopy = sal_uInt16(0 != ( a16Bit & 0x8000 )); | ||||||
6929 | |||||||
6930 | if( 4 > nRead ) break; | ||||||
6931 | a16Bit = 0; | ||||||
6932 | m_rStream.ReadUInt16( a16Bit ); | ||||||
6933 | pStd->sgc = a16Bit & 0x000f ; | ||||||
6934 | pStd->istdBase = ( a16Bit & 0xfff0 ) >> 4; | ||||||
6935 | |||||||
6936 | if( 6 > nRead ) break; | ||||||
6937 | a16Bit = 0; | ||||||
6938 | m_rStream.ReadUInt16( a16Bit ); | ||||||
6939 | pStd->cupx = a16Bit & 0x000f ; | ||||||
6940 | pStd->istdNext = ( a16Bit & 0xfff0 ) >> 4; | ||||||
6941 | |||||||
6942 | if( 8 > nRead ) break; | ||||||
6943 | m_rStream.ReadUInt16( pStd->bchUpe ); | ||||||
6944 | |||||||
6945 | // from Ver8 this two fields should be added: | ||||||
6946 | if(10 > nRead ) break; | ||||||
6947 | a16Bit = 0; | ||||||
6948 | m_rStream.ReadUInt16( a16Bit ); | ||||||
6949 | pStd->fAutoRedef = a16Bit & 0x0001 ; | ||||||
6950 | pStd->fHidden = ( a16Bit & 0x0002 ) >> 1; | ||||||
6951 | // You never know: cautionary skipped | ||||||
6952 | if (nRead > 10) | ||||||
6953 | { | ||||||
6954 | auto nSkip = std::min<sal_uInt64>(nRead - 10, m_rStream.remainingSize()); | ||||||
6955 | m_rStream.Seek(m_rStream.Tell() + nSkip); | ||||||
6956 | } | ||||||
6957 | } | ||||||
6958 | while( false ); // trick: the block above will passed through exactly one time | ||||||
6959 | // and can be left early with a "break" | ||||||
6960 | |||||||
6961 | if (!m_rStream.good() || !nRead) | ||||||
6962 | { | ||||||
6963 | pStd.reset(); // report error with NULL | ||||||
6964 | } | ||||||
6965 | |||||||
6966 | rSkip = cbStd - m_cbSTDBaseInFile; | ||||||
6967 | } | ||||||
6968 | else | ||||||
6969 | { // Fixed part too short | ||||||
6970 | if( cbStd ) | ||||||
6971 | m_rStream.SeekRel( cbStd ); // skip leftovers | ||||||
6972 | rSkip = 0; | ||||||
6973 | } | ||||||
6974 | return pStd; | ||||||
6975 | } | ||||||
6976 | |||||||
6977 | std::unique_ptr<WW8_STD> WW8Style::Read1Style(sal_uInt16& rSkip, OUString* pString) | ||||||
6978 | { | ||||||
6979 | // Attention: MacWord-Documents have their Stylenames | ||||||
6980 | // always in ANSI, even if eStructCharSet == CHARSET_MAC !! | ||||||
6981 | |||||||
6982 | std::unique_ptr<WW8_STD> pStd = Read1STDFixed(rSkip); // read STD | ||||||
6983 | |||||||
6984 | // string desired? | ||||||
6985 | if( pString ) | ||||||
6986 | { // real style? | ||||||
6987 | if ( pStd ) | ||||||
6988 | { | ||||||
6989 | sal_Int32 nLenStringBytes = 0; | ||||||
6990 | switch( m_rFib.m_nVersion ) | ||||||
6991 | { | ||||||
6992 | case 6: | ||||||
6993 | case 7: | ||||||
6994 | // read pascal string | ||||||
6995 | *pString = read_uInt8_BeltAndBracesString(m_rStream, RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1))); | ||||||
6996 | // leading len and trailing zero --> 2 | ||||||
6997 | nLenStringBytes = pString->getLength() + 2; | ||||||
6998 | break; | ||||||
6999 | case 8: | ||||||
7000 | // handle Unicode-String with leading length short and | ||||||
7001 | // trailing zero | ||||||
7002 | if (TestBeltAndBraces(m_rStream)) | ||||||
7003 | { | ||||||
7004 | *pString = read_uInt16_BeltAndBracesString(m_rStream); | ||||||
7005 | nLenStringBytes = (pString->getLength() + 2) * 2; | ||||||
7006 | } | ||||||
7007 | else | ||||||
7008 | { | ||||||
7009 | /* | ||||||
7010 | #i8114# | ||||||
7011 | This is supposed to be impossible, it's just supposed | ||||||
7012 | to be 16 bit count followed by the string and ending | ||||||
7013 | in a 0 short. But "Lotus SmartSuite Product: Word Pro" | ||||||
7014 | is creating invalid style names in ww7- format. So we | ||||||
7015 | use the belt and braces of the ms strings to see if | ||||||
7016 | they are not corrupt. If they are then we try them as | ||||||
7017 | 8bit ones | ||||||
7018 | */ | ||||||
7019 | *pString = read_uInt8_BeltAndBracesString(m_rStream,RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1))); | ||||||
7020 | // leading len and trailing zero --> 2 | ||||||
7021 | nLenStringBytes = pString->getLength() + 2; | ||||||
7022 | } | ||||||
7023 | break; | ||||||
7024 | default: | ||||||
7025 | OSL_ENSURE(false, "It was forgotten to code nVersion!")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7025" ": "), "%s", "It was forgotten to code nVersion!" ); } } while (false); | ||||||
7026 | break; | ||||||
7027 | } | ||||||
7028 | if (nLenStringBytes > rSkip) | ||||||
7029 | { | ||||||
7030 | SAL_WARN("sw.ww8", "WW8Style structure corrupt")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "WW8Style structure corrupt" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7030" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "WW8Style structure corrupt"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "WW8Style structure corrupt"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7030" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "WW8Style structure corrupt") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7030" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "WW8Style structure corrupt"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "WW8Style structure corrupt"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7030" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7031 | nLenStringBytes = rSkip; | ||||||
7032 | } | ||||||
7033 | rSkip -= nLenStringBytes; | ||||||
7034 | } | ||||||
7035 | else | ||||||
7036 | pString->clear(); // can not return a name | ||||||
7037 | } | ||||||
7038 | return pStd; | ||||||
7039 | } | ||||||
7040 | |||||||
7041 | namespace { | ||||||
7042 | const sal_uInt16 maxStrSize = 65; | ||||||
7043 | |||||||
7044 | struct WW8_FFN_Ver6 | ||||||
7045 | { | ||||||
7046 | WW8_FFN_BASE base; | ||||||
7047 | // from Ver6 | ||||||
7048 | char szFfn[maxStrSize]; // 0x6 or 0x40 from Ver8 on zero terminated string that | ||||||
7049 | // records name of font. | ||||||
7050 | // Maximal size of szFfn is 65 characters. | ||||||
7051 | // Attention: This array can also be smaller!!! | ||||||
7052 | // Possibly followed by a second sz which records the | ||||||
7053 | // name of an alternate font to use if the first named | ||||||
7054 | // font does not exist on this system. | ||||||
7055 | }; | ||||||
7056 | |||||||
7057 | } | ||||||
7058 | |||||||
7059 | // #i43762# check font name for illegal characters | ||||||
7060 | static void lcl_checkFontname( OUString& sString ) | ||||||
7061 | { | ||||||
7062 | // for efficiency, we'd like to use String methods as far as possible. | ||||||
7063 | // Hence, we will: | ||||||
7064 | // 1) convert all invalid chars to \u0001 | ||||||
7065 | // 2) then erase all \u0001 chars (if anywhere found), and | ||||||
7066 | // 3) erase leading/trailing ';', in case a font name was | ||||||
7067 | // completely removed | ||||||
7068 | |||||||
7069 | // convert all invalid chars to \u0001 | ||||||
7070 | OUStringBuffer aBuf(sString); | ||||||
7071 | const sal_Int32 nLen = aBuf.getLength(); | ||||||
7072 | bool bFound = false; | ||||||
7073 | for ( sal_Int32 n = 0; n < nLen; ++n ) | ||||||
7074 | { | ||||||
7075 | if ( aBuf[n] < 0x20 ) | ||||||
7076 | { | ||||||
7077 | aBuf[n] = 1; | ||||||
7078 | bFound = true; | ||||||
7079 | } | ||||||
7080 | } | ||||||
7081 | sString = aBuf.makeStringAndClear(); | ||||||
7082 | |||||||
7083 | // if anything was found, remove \u0001 + leading/trailing ';' | ||||||
7084 | if( bFound ) | ||||||
7085 | { | ||||||
7086 | sString = comphelper::string::strip(sString.replaceAll("\001", ""), ';'); | ||||||
7087 | } | ||||||
7088 | } | ||||||
7089 | |||||||
7090 | namespace | ||||||
7091 | { | ||||||
7092 | sal_uInt16 calcMaxFonts(sal_uInt8 *p, sal_Int32 nFFn) | ||||||
7093 | { | ||||||
7094 | // Figure out the max number of fonts defined here | ||||||
7095 | sal_uInt16 nMax = 0; | ||||||
7096 | sal_Int32 nRemaining = nFFn; | ||||||
7097 | while (nRemaining) | ||||||
7098 | { | ||||||
7099 | //p[0] is cbFfnM1, the alleged total length of FFN - 1. | ||||||
7100 | //i.e. length after cbFfnM1 | ||||||
7101 | const sal_uInt16 cbFfnM1 = *p++; | ||||||
7102 | --nRemaining; | ||||||
7103 | |||||||
7104 | if (cbFfnM1 > nRemaining) | ||||||
7105 | break; | ||||||
7106 | |||||||
7107 | nMax++; | ||||||
7108 | nRemaining -= cbFfnM1; | ||||||
7109 | p += cbFfnM1; | ||||||
7110 | } | ||||||
7111 | return nMax; | ||||||
7112 | } | ||||||
7113 | |||||||
7114 | template<typename T> bool readU8( | ||||||
7115 | sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd, | ||||||
7116 | T * value) | ||||||
7117 | { | ||||||
7118 | assert(p <= pEnd)(static_cast <bool> (p <= pEnd) ? void (0) : __assert_fail ("p <= pEnd", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7118, __extension__ __PRETTY_FUNCTION__)); | ||||||
7119 | assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail ("value != nullptr", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7119, __extension__ __PRETTY_FUNCTION__)); | ||||||
7120 | if (offset >= o3tl::make_unsigned(pEnd - p)) { | ||||||
7121 | return false; | ||||||
7122 | } | ||||||
7123 | *value = p[offset]; | ||||||
7124 | return true; | ||||||
7125 | } | ||||||
7126 | |||||||
7127 | bool readS16( | ||||||
7128 | sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd, | ||||||
7129 | short * value) | ||||||
7130 | { | ||||||
7131 | assert(p <= pEnd)(static_cast <bool> (p <= pEnd) ? void (0) : __assert_fail ("p <= pEnd", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7131, __extension__ __PRETTY_FUNCTION__)); | ||||||
7132 | assert(value != nullptr)(static_cast <bool> (value != nullptr) ? void (0) : __assert_fail ("value != nullptr", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7132, __extension__ __PRETTY_FUNCTION__)); | ||||||
7133 | if (offset > o3tl::make_unsigned(pEnd - p) | ||||||
7134 | || static_cast<std::size_t>(pEnd - p) - offset < 2) | ||||||
7135 | { | ||||||
7136 | return false; | ||||||
7137 | } | ||||||
7138 | *value = unsigned(p[offset]) + (unsigned(p[offset + 1]) << 8); | ||||||
7139 | return true; | ||||||
7140 | } | ||||||
7141 | |||||||
7142 | sal_Int32 getStringLength( | ||||||
7143 | sal_uInt8 const * p, std::size_t offset, sal_uInt8 const * pEnd) | ||||||
7144 | { | ||||||
7145 | assert(p <= pEnd)(static_cast <bool> (p <= pEnd) ? void (0) : __assert_fail ("p <= pEnd", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7145, __extension__ __PRETTY_FUNCTION__)); | ||||||
7146 | assert(pEnd - p <= SAL_MAX_INT32)(static_cast <bool> (pEnd - p <= ((sal_Int32) 0x7FFFFFFF )) ? void (0) : __assert_fail ("pEnd - p <= SAL_MAX_INT32" , "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7146, __extension__ __PRETTY_FUNCTION__)); | ||||||
7147 | if (offset >= o3tl::make_unsigned(pEnd - p)) { | ||||||
7148 | return -1; | ||||||
7149 | } | ||||||
7150 | void const * p2 = std::memchr( | ||||||
7151 | p + offset, 0, static_cast<std::size_t>(pEnd - p) - offset); | ||||||
7152 | if (p2 == nullptr) { | ||||||
7153 | return -1; | ||||||
7154 | } | ||||||
7155 | return static_cast<sal_uInt8 const *>(p2) - (p + offset); | ||||||
7156 | } | ||||||
7157 | } | ||||||
7158 | |||||||
7159 | WW8Fonts::WW8Fonts( SvStream& rSt, WW8Fib const & rFib ) | ||||||
7160 | { | ||||||
7161 | // Attention: MacWord-Documents have their Fontnames | ||||||
7162 | // always in ANSI, even if eStructCharSet == CHARSET_MAC !! | ||||||
7163 | if( rFib.m_lcbSttbfffn <= 2 ) | ||||||
7164 | { | ||||||
7165 | OSL_ENSURE( false, "font table is broken! (rFib.lcbSttbfffn < 2)" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7165" ": "), "%s", "font table is broken! (rFib.lcbSttbfffn < 2)" ); } } while (false); | ||||||
7166 | return; | ||||||
7167 | } | ||||||
7168 | |||||||
7169 | if (!checkSeek(rSt, rFib.m_fcSttbfffn)) | ||||||
7170 | return; | ||||||
7171 | |||||||
7172 | sal_Int32 nFFn = rFib.m_lcbSttbfffn - 2; | ||||||
7173 | |||||||
7174 | const sal_uInt64 nMaxPossible = rSt.remainingSize(); | ||||||
7175 | if (o3tl::make_unsigned(nFFn) > nMaxPossible) | ||||||
7176 | { | ||||||
7177 | SAL_WARN("sw.ww8", "FFN structure longer than available data")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "FFN structure longer than available data" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "FFN structure longer than available data" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "FFN structure longer than available data"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7177" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "FFN structure longer than available data") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7177" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "FFN structure longer than available data" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "FFN structure longer than available data"; ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7177" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7178 | nFFn = nMaxPossible; | ||||||
7179 | } | ||||||
7180 | |||||||
7181 | // allocate Font Array | ||||||
7182 | std::vector<sal_uInt8> aA(nFFn); | ||||||
7183 | memset(aA.data(), 0, nFFn); | ||||||
7184 | |||||||
7185 | ww::WordVersion eVersion = rFib.GetFIBVersion(); | ||||||
7186 | |||||||
7187 | sal_uInt16 nMax(0); | ||||||
7188 | if( eVersion >= ww::eWW8 ) | ||||||
7189 | { | ||||||
7190 | // bVer8: read the count of strings in nMax | ||||||
7191 | rSt.ReadUInt16(nMax); | ||||||
7192 | } | ||||||
7193 | |||||||
7194 | // Ver8: skip undefined uint16 | ||||||
7195 | // Ver67: skip the herein stored total byte of structure | ||||||
7196 | // - we already got that information in rFib.lcbSttbfffn | ||||||
7197 | rSt.SeekRel( 2 ); | ||||||
7198 | |||||||
7199 | // read all font information | ||||||
7200 | nFFn = rSt.ReadBytes(aA.data(), nFFn); | ||||||
7201 | sal_uInt8 * const pEnd = aA.data() + nFFn; | ||||||
7202 | const sal_uInt16 nCalcMax = calcMaxFonts(aA.data(), nFFn); | ||||||
7203 | |||||||
7204 | if (eVersion < ww::eWW8) | ||||||
7205 | nMax = nCalcMax; | ||||||
7206 | else | ||||||
7207 | { | ||||||
7208 | //newer versions include supportive count of fonts, so take min of that | ||||||
7209 | //and calced max | ||||||
7210 | nMax = std::min(nMax, nCalcMax); | ||||||
7211 | } | ||||||
7212 | |||||||
7213 | if (nMax) | ||||||
7214 | { | ||||||
7215 | // allocate Index Array | ||||||
7216 | m_aFontA.resize(nMax); | ||||||
7217 | WW8_FFN* p = m_aFontA.data(); | ||||||
7218 | |||||||
7219 | if( eVersion <= ww::eWW2 ) | ||||||
7220 | { | ||||||
7221 | sal_uInt8 const * pVer2 = aA.data(); | ||||||
7222 | sal_uInt16 i = 0; | ||||||
7223 | for(; i<nMax; ++i, ++p) | ||||||
7224 | { | ||||||
7225 | if (!readU8( | ||||||
7226 | pVer2, offsetof(WW8_FFN_BASE, cbFfnM1)__builtin_offsetof(WW8_FFN_BASE, cbFfnM1), pEnd, | ||||||
7227 | &p->aFFNBase.cbFfnM1)) | ||||||
7228 | { | ||||||
7229 | break; | ||||||
7230 | } | ||||||
7231 | |||||||
7232 | p->aFFNBase.prg = 0; | ||||||
7233 | p->aFFNBase.fTrueType = 0; | ||||||
7234 | p->aFFNBase.ff = 0; | ||||||
7235 | |||||||
7236 | if (!(readU8(pVer2, 1, pEnd, &p->aFFNBase.wWeight) | ||||||
7237 | && readU8(pVer2, 2, pEnd, &p->aFFNBase.chs))) | ||||||
7238 | { | ||||||
7239 | break; | ||||||
7240 | } | ||||||
7241 | /* | ||||||
7242 | #i8726# 7- seems to encode the name in the same encoding as | ||||||
7243 | the font, e.g load the doc in 97 and save to see the unicode | ||||||
7244 | ver of the asian fontnames in that example to confirm. | ||||||
7245 | */ | ||||||
7246 | rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid); | ||||||
7247 | if ((eEnc == RTL_TEXTENCODING_SYMBOL(((rtl_TextEncoding) 10))) || (eEnc == RTL_TEXTENCODING_DONTKNOW(((rtl_TextEncoding) 0)))) | ||||||
7248 | eEnc = RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1)); | ||||||
7249 | |||||||
7250 | sal_Int32 n = getStringLength(pVer2, 1 + 2, pEnd); | ||||||
7251 | if (n == -1) { | ||||||
7252 | break; | ||||||
7253 | } | ||||||
7254 | p->sFontname = OUString( | ||||||
7255 | reinterpret_cast<char const *>(pVer2 + 1 + 2), n, eEnc); | ||||||
7256 | pVer2 = pVer2 + p->aFFNBase.cbFfnM1 + 1; | ||||||
7257 | } | ||||||
7258 | nMax = i; | ||||||
7259 | } | ||||||
7260 | else if( eVersion < ww::eWW8 ) | ||||||
7261 | { | ||||||
7262 | sal_uInt8 const * pVer6 = aA.data(); | ||||||
7263 | sal_uInt16 i = 0; | ||||||
7264 | for(; i<nMax; ++i, ++p) | ||||||
7265 | { | ||||||
7266 | if (!readU8( | ||||||
7267 | pVer6, offsetof(WW8_FFN_BASE, cbFfnM1)__builtin_offsetof(WW8_FFN_BASE, cbFfnM1), pEnd, | ||||||
7268 | &p->aFFNBase.cbFfnM1)) | ||||||
7269 | { | ||||||
7270 | break; | ||||||
7271 | } | ||||||
7272 | sal_uInt8 c2; | ||||||
7273 | if (!readU8(pVer6, 1, pEnd, &c2)) { | ||||||
7274 | break; | ||||||
7275 | } | ||||||
7276 | |||||||
7277 | p->aFFNBase.prg = c2 & 0x02; | ||||||
7278 | p->aFFNBase.fTrueType = (c2 & 0x04) >> 2; | ||||||
7279 | // skip a reserve bit | ||||||
7280 | p->aFFNBase.ff = (c2 & 0x70) >> 4; | ||||||
7281 | |||||||
7282 | if (!(readS16( | ||||||
7283 | pVer6, offsetof(WW8_FFN_BASE, wWeight)__builtin_offsetof(WW8_FFN_BASE, wWeight), pEnd, | ||||||
7284 | &p->aFFNBase.wWeight) | ||||||
7285 | && readU8( | ||||||
7286 | pVer6, offsetof(WW8_FFN_BASE, chs)__builtin_offsetof(WW8_FFN_BASE, chs), pEnd, &p->aFFNBase.chs) | ||||||
7287 | && readU8( | ||||||
7288 | pVer6, offsetof(WW8_FFN_BASE, ibszAlt)__builtin_offsetof(WW8_FFN_BASE, ibszAlt), pEnd, | ||||||
7289 | &p->aFFNBase.ibszAlt))) | ||||||
7290 | { | ||||||
7291 | break; | ||||||
7292 | } | ||||||
7293 | /* | ||||||
7294 | #i8726# 7- seems to encode the name in the same encoding as | ||||||
7295 | the font, e.g load the doc in 97 and save to see the unicode | ||||||
7296 | ver of the asian fontnames in that example to confirm. | ||||||
7297 | */ | ||||||
7298 | rtl_TextEncoding eEnc = WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid); | ||||||
7299 | if ((eEnc == RTL_TEXTENCODING_SYMBOL(((rtl_TextEncoding) 10))) || (eEnc == RTL_TEXTENCODING_DONTKNOW(((rtl_TextEncoding) 0)))) | ||||||
7300 | eEnc = RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1)); | ||||||
7301 | sal_Int32 n = getStringLength( | ||||||
7302 | pVer6, offsetof(WW8_FFN_Ver6, szFfn)__builtin_offsetof(WW8_FFN_Ver6, szFfn), pEnd); | ||||||
7303 | if (n == -1) { | ||||||
7304 | break; | ||||||
7305 | } | ||||||
7306 | p->sFontname = OUString( | ||||||
7307 | reinterpret_cast<char const *>( | ||||||
7308 | pVer6 + offsetof(WW8_FFN_Ver6, szFfn)__builtin_offsetof(WW8_FFN_Ver6, szFfn)), | ||||||
7309 | n, eEnc); | ||||||
7310 | if (p->aFFNBase.ibszAlt && p->aFFNBase.ibszAlt < maxStrSize) //don't start after end of string | ||||||
7311 | { | ||||||
7312 | n = getStringLength( | ||||||
7313 | pVer6, offsetof(WW8_FFN_Ver6, szFfn)__builtin_offsetof(WW8_FFN_Ver6, szFfn) + p->aFFNBase.ibszAlt, | ||||||
7314 | pEnd); | ||||||
7315 | if (n == -1) { | ||||||
7316 | break; | ||||||
7317 | } | ||||||
7318 | p->sFontname += ";" + OUString( | ||||||
7319 | reinterpret_cast<char const *>( | ||||||
7320 | pVer6 + offsetof(WW8_FFN_Ver6, szFfn)__builtin_offsetof(WW8_FFN_Ver6, szFfn) + p->aFFNBase.ibszAlt), | ||||||
7321 | n, eEnc); | ||||||
7322 | } | ||||||
7323 | else | ||||||
7324 | { | ||||||
7325 | //#i18369# if it's a symbol font set Symbol as fallback | ||||||
7326 | if ( | ||||||
7327 | RTL_TEXTENCODING_SYMBOL(((rtl_TextEncoding) 10)) == WW8Fib::GetFIBCharset(p->aFFNBase.chs, rFib.m_lid) | ||||||
7328 | && p->sFontname!="Symbol" | ||||||
7329 | ) | ||||||
7330 | { | ||||||
7331 | p->sFontname += ";Symbol"; | ||||||
7332 | } | ||||||
7333 | } | ||||||
7334 | pVer6 = pVer6 + p->aFFNBase.cbFfnM1 + 1; | ||||||
7335 | } | ||||||
7336 | nMax = i; | ||||||
7337 | } | ||||||
7338 | else | ||||||
7339 | { | ||||||
7340 | //count of bytes in minimum FontFamilyInformation payload | ||||||
7341 | const sal_uInt8 cbMinFFNPayload = 41; | ||||||
7342 | sal_uInt16 nValidFonts = 0; | ||||||
7343 | sal_Int32 nRemainingFFn = nFFn; | ||||||
7344 | sal_uInt8* pRaw = aA.data(); | ||||||
7345 | for (sal_uInt16 i=0; i < nMax && nRemainingFFn; ++i, ++p) | ||||||
7346 | { | ||||||
7347 | //pRaw[0] is cbFfnM1, the alleged total length of FFN - 1 | ||||||
7348 | //i.e. length after cbFfnM1 | ||||||
7349 | sal_uInt8 cbFfnM1 = *pRaw++; | ||||||
7350 | --nRemainingFFn; | ||||||
7351 | |||||||
7352 | if (cbFfnM1 > nRemainingFFn) | ||||||
7353 | break; | ||||||
7354 | |||||||
7355 | if (cbFfnM1 < cbMinFFNPayload) | ||||||
7356 | break; | ||||||
7357 | |||||||
7358 | p->aFFNBase.cbFfnM1 = cbFfnM1; | ||||||
7359 | |||||||
7360 | sal_uInt8 *pVer8 = pRaw; | ||||||
7361 | |||||||
7362 | sal_uInt8 c2 = *pVer8++; | ||||||
7363 | --cbFfnM1; | ||||||
7364 | |||||||
7365 | p->aFFNBase.prg = c2 & 0x02; | ||||||
7366 | p->aFFNBase.fTrueType = (c2 & 0x04) >> 2; | ||||||
7367 | // skip a reserve bit | ||||||
7368 | p->aFFNBase.ff = (c2 & 0x70) >> 4; | ||||||
7369 | |||||||
7370 | p->aFFNBase.wWeight = SVBT16ToUInt16(*reinterpret_cast<SVBT16*>(pVer8)); | ||||||
7371 | pVer8+=2; | ||||||
7372 | cbFfnM1-=2; | ||||||
7373 | |||||||
7374 | p->aFFNBase.chs = *pVer8++; | ||||||
7375 | --cbFfnM1; | ||||||
7376 | |||||||
7377 | p->aFFNBase.ibszAlt = *pVer8++; | ||||||
7378 | --cbFfnM1; | ||||||
7379 | |||||||
7380 | pVer8 += 10; //PANOSE | ||||||
7381 | cbFfnM1-=10; | ||||||
7382 | pVer8 += 24; //FONTSIGNATURE | ||||||
7383 | cbFfnM1-=24; | ||||||
7384 | |||||||
7385 | assert(cbFfnM1 >= 2)(static_cast <bool> (cbFfnM1 >= 2) ? void (0) : __assert_fail ("cbFfnM1 >= 2", "/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" , 7385, __extension__ __PRETTY_FUNCTION__)); | ||||||
7386 | |||||||
7387 | sal_uInt8 nMaxNullTerminatedPossible = cbFfnM1/2 - 1; | ||||||
7388 | sal_Unicode *pPrimary = reinterpret_cast<sal_Unicode*>(pVer8); | ||||||
7389 | pPrimary[nMaxNullTerminatedPossible] = 0; | ||||||
7390 | #ifdef OSL_BIGENDIAN | ||||||
7391 | swapEndian(pPrimary); | ||||||
7392 | #endif | ||||||
7393 | p->sFontname = pPrimary; | ||||||
7394 | if (p->aFFNBase.ibszAlt && p->aFFNBase.ibszAlt < nMaxNullTerminatedPossible) | ||||||
7395 | { | ||||||
7396 | sal_Unicode *pSecondary = pPrimary + p->aFFNBase.ibszAlt; | ||||||
7397 | #ifdef OSL_BIGENDIAN | ||||||
7398 | swapEndian(pSecondary); | ||||||
7399 | #endif | ||||||
7400 | p->sFontname += OUStringLiteral(u";") + pSecondary; | ||||||
7401 | } | ||||||
7402 | |||||||
7403 | // #i43762# check font name for illegal characters | ||||||
7404 | lcl_checkFontname( p->sFontname ); | ||||||
7405 | |||||||
7406 | // set pointer one font back to original array | ||||||
7407 | pRaw += p->aFFNBase.cbFfnM1; | ||||||
7408 | nRemainingFFn -= p->aFFNBase.cbFfnM1; | ||||||
7409 | ++nValidFonts; | ||||||
7410 | } | ||||||
7411 | OSL_ENSURE(nMax == nValidFonts, "Font count differs with availability")do { if (true && (!(nMax == nValidFonts))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7411" ": "), "%s", "Font count differs with availability" ); } } while (false); | ||||||
7412 | nMax = std::min(nMax, nValidFonts); | ||||||
7413 | } | ||||||
7414 | } | ||||||
7415 | m_aFontA.resize(nMax); | ||||||
7416 | m_aFontA.shrink_to_fit(); | ||||||
7417 | } | ||||||
7418 | |||||||
7419 | const WW8_FFN* WW8Fonts::GetFont( sal_uInt16 nNum ) const | ||||||
7420 | { | ||||||
7421 | if (nNum >= m_aFontA.size()) | ||||||
7422 | return nullptr; | ||||||
7423 | |||||||
7424 | return &m_aFontA[nNum]; | ||||||
7425 | } | ||||||
7426 | |||||||
7427 | // Search after a header/footer for an index in the ww list from header/footer | ||||||
7428 | |||||||
7429 | // specials for WinWord6 and -7: | ||||||
7430 | // | ||||||
7431 | // 1) At the start of reading we must build WWPLCF_HdFt with Fib and Dop | ||||||
7432 | // 2) The main text must be read sequentially over all sections | ||||||
7433 | // 3) For every header/footer in the main text, we must call UpdateIndex() | ||||||
7434 | // exactly once with the parameter from the attribute. | ||||||
7435 | // (per section can be maximally one). This call must take place *after* | ||||||
7436 | // the last call from GetTextPos(). | ||||||
7437 | // 4) GetTextPos() can be called with exactly one flag | ||||||
7438 | // out of WW8_{FOOTER,HEADER}_{ODD,EVEN,FIRST} (Do not change!) | ||||||
7439 | // -> maybe we can get a right result then | ||||||
7440 | |||||||
7441 | WW8PLCF_HdFt::WW8PLCF_HdFt( SvStream* pSt, WW8Fib const & rFib, WW8Dop const & rDop ) | ||||||
7442 | : aPLCF(*pSt, rFib.m_fcPlcfhdd , rFib.m_lcbPlcfhdd , 0) | ||||||
7443 | { | ||||||
7444 | nIdxOffset = 0; | ||||||
7445 | |||||||
7446 | /* | ||||||
7447 | This dop.grpfIhdt has a bit set for each special | ||||||
7448 | footnote *and endnote!!* separator,continuation separator, and | ||||||
7449 | continuation notice entry, the documentation does not mention the | ||||||
7450 | endnote separators, the documentation also gets the index numbers | ||||||
7451 | backwards when specifying which bits to test. The bottom six bits | ||||||
7452 | of this value must be tested and skipped over. Each section's | ||||||
7453 | grpfIhdt is then tested for the existence of the appropriate headers | ||||||
7454 | and footers, at the end of each section the nIdxOffset must be updated | ||||||
7455 | to point to the beginning of the next section's group of headers and | ||||||
7456 | footers in this PLCF, UpdateIndex does that task. | ||||||
7457 | */ | ||||||
7458 | for( sal_uInt8 nI = 0x1; nI <= 0x20; nI <<= 1 ) | ||||||
7459 | if( nI & rDop.grpfIhdt ) // bit set? | ||||||
7460 | nIdxOffset++; | ||||||
7461 | } | ||||||
7462 | |||||||
7463 | bool WW8PLCF_HdFt::GetTextPos(sal_uInt8 grpfIhdt, sal_uInt8 nWhich, WW8_CP& rStart, | ||||||
7464 | WW8_CP& rLen) | ||||||
7465 | { | ||||||
7466 | sal_uInt8 nI = 0x01; | ||||||
7467 | short nIdx = nIdxOffset; | ||||||
7468 | while (true) | ||||||
7469 | { | ||||||
7470 | if( nI & nWhich ) | ||||||
7471 | break; // found | ||||||
7472 | if( grpfIhdt & nI ) | ||||||
7473 | nIdx++; // uninteresting Header / Footer | ||||||
7474 | nI <<= 1; // text next bit | ||||||
7475 | if( nI > 0x20 ) | ||||||
7476 | return false; // not found | ||||||
7477 | } | ||||||
7478 | // nIdx is HdFt-Index | ||||||
7479 | WW8_CP nEnd; | ||||||
7480 | void* pData; | ||||||
7481 | |||||||
7482 | aPLCF.SetIdx( nIdx ); // Lookup suitable CP | ||||||
7483 | aPLCF.Get( rStart, nEnd, pData ); | ||||||
7484 | if (nEnd < rStart) | ||||||
7485 | { | ||||||
7486 | SAL_WARN("sw.ww8", "End " << nEnd << " before Start " << rStart)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << nEnd << " before Start " << rStart) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7486" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEnd << " before Start " << rStart), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEnd << " before Start " << rStart; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7486" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << nEnd << " before Start " << rStart) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7486" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEnd << " before Start " << rStart), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEnd << " before Start " << rStart; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7486" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7487 | return false; | ||||||
7488 | } | ||||||
7489 | |||||||
7490 | bool bFail = o3tl::checked_sub(nEnd, rStart, rLen); | ||||||
7491 | if (bFail) | ||||||
7492 | { | ||||||
7493 | SAL_WARN("sw.ww8", "broken offset, ignoring")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "broken offset, ignoring" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7493" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7493" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "broken offset, ignoring") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7493" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "broken offset, ignoring"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "broken offset, ignoring"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7493" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7494 | return false; | ||||||
7495 | } | ||||||
7496 | |||||||
7497 | aPLCF.advance(); | ||||||
7498 | |||||||
7499 | return true; | ||||||
7500 | } | ||||||
7501 | |||||||
7502 | void WW8PLCF_HdFt::GetTextPosExact(short nIdx, WW8_CP& rStart, WW8_CP& rLen) | ||||||
7503 | { | ||||||
7504 | WW8_CP nEnd; | ||||||
7505 | void* pData; | ||||||
7506 | |||||||
7507 | aPLCF.SetIdx( nIdx ); // Lookup suitable CP | ||||||
7508 | aPLCF.Get( rStart, nEnd, pData ); | ||||||
7509 | if (nEnd < rStart) | ||||||
7510 | { | ||||||
7511 | SAL_WARN("sw.ww8", "End " << nEnd << " before Start " << rStart)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "End " << nEnd << " before Start " << rStart) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7511" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEnd << " before Start " << rStart), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEnd << " before Start " << rStart; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7511" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "End " << nEnd << " before Start " << rStart) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7511" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "End " << nEnd << " before Start " << rStart), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "End " << nEnd << " before Start " << rStart; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7511" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7512 | rLen = 0; | ||||||
7513 | return; | ||||||
7514 | } | ||||||
7515 | if (o3tl::checked_sub(nEnd, rStart, rLen)) | ||||||
7516 | { | ||||||
7517 | SAL_WARN("sw.ww8", "GetTextPosExact overflow")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "GetTextPosExact overflow" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7517" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "GetTextPosExact overflow"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "GetTextPosExact overflow"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7517" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "GetTextPosExact overflow") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7517" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "GetTextPosExact overflow"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "GetTextPosExact overflow"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("sw.ww8"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "7517" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
7518 | rLen = 0; | ||||||
7519 | } | ||||||
7520 | } | ||||||
7521 | |||||||
7522 | void WW8PLCF_HdFt::UpdateIndex( sal_uInt8 grpfIhdt ) | ||||||
7523 | { | ||||||
7524 | // Caution: Description is not correct | ||||||
7525 | for( sal_uInt8 nI = 0x01; nI <= 0x20; nI <<= 1 ) | ||||||
7526 | if( nI & grpfIhdt ) | ||||||
7527 | nIdxOffset++; | ||||||
7528 | } | ||||||
7529 | |||||||
7530 | WW8Dop::WW8Dop(SvStream& rSt, sal_Int16 nFib, sal_Int32 nPos, sal_uInt32 nSize): | ||||||
7531 | fFacingPages(false), fWidowControl(false), fPMHMainDoc(false), grfSuppression(0), fpc(0), | ||||||
7532 | grpfIhdt(0), rncFootnote(0), nFootnote(0), fOutlineDirtySave(false), fOnlyMacPics(false), | ||||||
7533 | fOnlyWinPics(false), fLabelDoc(false), fHyphCapitals(false), fAutoHyphen(false), | ||||||
7534 | fFormNoFields(false), fLinkStyles(false), fRevMarking(false), fBackup(false), | ||||||
7535 | fExactCWords(false), fPagHidden(false), fPagResults(false), fLockAtn(false), | ||||||
7536 | fMirrorMargins(false), fReadOnlyRecommended(false), fDfltTrueType(false), | ||||||
7537 | fPagSuppressTopSpacing(false), fProtEnabled(false), fDispFormFieldSel(false), fRMView(false), | ||||||
7538 | fRMPrint(false), fWriteReservation(false), fLockRev(false), fEmbedFonts(false), | ||||||
7539 | copts_fNoTabForInd(false), copts_fNoSpaceRaiseLower(false), copts_fSupressSpbfAfterPgBrk(false), | ||||||
7540 | copts_fWrapTrailSpaces(false), copts_fMapPrintTextColor(false), copts_fNoColumnBalance(false), | ||||||
7541 | copts_fConvMailMergeEsc(false), copts_fSupressTopSpacing(false), | ||||||
7542 | copts_fOrigWordTableRules(false), copts_fTransparentMetafiles(false), | ||||||
7543 | copts_fShowBreaksInFrames(false), copts_fSwapBordersFacingPgs(false), copts_fExpShRtn(false), | ||||||
7544 | rncEdn(0), nEdn(0), epc(0), fPrintFormData(false), fSaveFormData(false), fShadeFormData(false), | ||||||
7545 | fWCFootnoteEdn(false), wvkSaved(0), wScaleSaved(0), zkSaved(0), fRotateFontW6(false), | ||||||
7546 | iGutterPos(false), fNoTabForInd(false), fNoSpaceRaiseLower(false), | ||||||
7547 | fSupressSpbfAfterPageBreak(false), fWrapTrailSpaces(false), fMapPrintTextColor(false), | ||||||
7548 | fNoColumnBalance(false), fConvMailMergeEsc(false), fSupressTopSpacing(false), | ||||||
7549 | fOrigWordTableRules(false), fTransparentMetafiles(false), fShowBreaksInFrames(false), | ||||||
7550 | fSwapBordersFacingPgs(false), fCompatibilityOptions_Unknown1_13(false), fExpShRtn(false), | ||||||
7551 | fCompatibilityOptions_Unknown1_15(false), fCompatibilityOptions_Unknown1_16(false), | ||||||
7552 | fSuppressTopSpacingMac5(false), fTruncDxaExpand(false), fPrintBodyBeforeHdr(false), | ||||||
7553 | fNoLeading(false), fCompatibilityOptions_Unknown1_21(false), fMWSmallCaps(false), | ||||||
7554 | fCompatibilityOptions_Unknown1_23(false), fCompatibilityOptions_Unknown1_24(false), | ||||||
7555 | fCompatibilityOptions_Unknown1_25(false), fCompatibilityOptions_Unknown1_26(false), | ||||||
7556 | fCompatibilityOptions_Unknown1_27(false), fCompatibilityOptions_Unknown1_28(false), | ||||||
7557 | fCompatibilityOptions_Unknown1_29(false), fCompatibilityOptions_Unknown1_30(false), | ||||||
7558 | fCompatibilityOptions_Unknown1_31(false), fUsePrinterMetrics(false), lvl(0), fHtmlDoc(false), | ||||||
7559 | fSnapBorder(false), fIncludeHeader(false), fIncludeFooter(false), fForcePageSizePag(false), | ||||||
7560 | fMinFontSizePag(false), fHaveVersions(false), fAutoVersion(false), | ||||||
7561 | fCompatibilityOptions_Unknown2_1(false), fCompatibilityOptions_Unknown2_2(false), | ||||||
7562 | fDontUseHTMLAutoSpacing(false), fCompatibilityOptions_Unknown2_4(false), | ||||||
7563 | fCompatibilityOptions_Unknown2_5(false), fCompatibilityOptions_Unknown2_6(false), | ||||||
7564 | fCompatibilityOptions_Unknown2_7(false), fCompatibilityOptions_Unknown2_8(false), | ||||||
7565 | fCompatibilityOptions_Unknown2_9(false), fCompatibilityOptions_Unknown2_10(false), | ||||||
7566 | fCompatibilityOptions_Unknown2_11(false), fCompatibilityOptions_Unknown2_12(false), | ||||||
7567 | fCompatibilityOptions_Unknown2_13(false), fCompatibilityOptions_Unknown2_14(false), | ||||||
7568 | fCompatibilityOptions_Unknown2_15(false), fCompatibilityOptions_Unknown2_16(false), | ||||||
7569 | fCompatibilityOptions_Unknown2_17(false), fCompatibilityOptions_Unknown2_18(false), | ||||||
7570 | fCompatibilityOptions_Unknown2_19(false), fCompatibilityOptions_Unknown2_20(false), | ||||||
7571 | fCompatibilityOptions_Unknown2_21(false), fCompatibilityOptions_Unknown2_22(false), | ||||||
7572 | fCompatibilityOptions_Unknown2_23(false), fCompatibilityOptions_Unknown2_24(false), | ||||||
7573 | fCompatibilityOptions_Unknown2_25(false), fCompatibilityOptions_Unknown2_26(false), | ||||||
7574 | fCompatibilityOptions_Unknown2_27(false), fCompatibilityOptions_Unknown2_28(false), | ||||||
7575 | fCompatibilityOptions_Unknown2_29(false), fCompatibilityOptions_Unknown2_30(false), | ||||||
7576 | fCompatibilityOptions_Unknown2_31(false), fCompatibilityOptions_Unknown2_32(false), | ||||||
7577 | fUnknown3(0), fUseBackGroundInAllmodes(false), fDoNotEmbedSystemFont(false), fWordCompat(false), | ||||||
7578 | fLiveRecover(false), fEmbedFactoids(false), fFactoidXML(false), fFactoidAllDone(false), | ||||||
7579 | fFolioPrint(false), fReverseFolio(false), iTextLineEnding(0), fHideFcc(false), | ||||||
7580 | fAcetateShowMarkup(false), fAcetateShowAtn(false), fAcetateShowInsDel(false), | ||||||
7581 | fAcetateShowProps(false) | ||||||
7582 | // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the | ||||||
7583 | // above bit-field member initializations can be moved to the class definition | ||||||
7584 | { | ||||||
7585 | fDontUseHTMLAutoSpacing = true; //default | ||||||
7586 | fAcetateShowAtn = true; //default | ||||||
7587 | const sal_uInt32 nMaxDopSize = 0x268; | ||||||
7588 | std::unique_ptr<sal_uInt8[]> pDataPtr( new sal_uInt8[ nMaxDopSize ] ); | ||||||
7589 | sal_uInt8* pData = pDataPtr.get(); | ||||||
7590 | |||||||
7591 | sal_uInt32 nRead = std::min(nMaxDopSize, nSize); | ||||||
7592 | if (nSize < 2 || !checkSeek(rSt, nPos) || nRead != rSt.ReadBytes(pData, nRead)) | ||||||
7593 | nDopError = ERR_SWG_READ_ERRORErrCode(ErrCodeArea::Sw, ErrCodeClass::Read, 2 ); // report error | ||||||
7594 | else | ||||||
7595 | { | ||||||
7596 | if (nMaxDopSize > nRead) | ||||||
7597 | memset( pData + nRead, 0, nMaxDopSize - nRead ); | ||||||
7598 | |||||||
7599 | // interpret the data | ||||||
7600 | sal_uInt32 a32Bit; | ||||||
7601 | sal_uInt16 a16Bit; | ||||||
7602 | sal_uInt8 a8Bit; | ||||||
7603 | |||||||
7604 | a16Bit = Get_UShort( pData ); // 0 0x00 | ||||||
7605 | fFacingPages = 0 != ( a16Bit & 0x0001 ) ; | ||||||
7606 | fWidowControl = 0 != ( a16Bit & 0x0002 ) ; | ||||||
7607 | fPMHMainDoc = 0 != ( a16Bit & 0x0004 ) ; | ||||||
7608 | grfSuppression = ( a16Bit & 0x0018 ) >> 3; | ||||||
7609 | fpc = ( a16Bit & 0x0060 ) >> 5; | ||||||
7610 | grpfIhdt = ( a16Bit & 0xff00 ) >> 8; | ||||||
7611 | |||||||
7612 | a16Bit = Get_UShort( pData ); // 2 0x02 | ||||||
7613 | rncFootnote = a16Bit & 0x0003 ; | ||||||
7614 | nFootnote = ( a16Bit & ~0x0003 ) >> 2 ; | ||||||
7615 | |||||||
7616 | a8Bit = Get_Byte( pData ); // 4 0x04 | ||||||
7617 | fOutlineDirtySave = 0 != ( a8Bit & 0x01 ); | ||||||
7618 | |||||||
7619 | a8Bit = Get_Byte( pData ); // 5 0x05 | ||||||
7620 | fOnlyMacPics = 0 != ( a8Bit & 0x01 ); | ||||||
7621 | fOnlyWinPics = 0 != ( a8Bit & 0x02 ); | ||||||
7622 | fLabelDoc = 0 != ( a8Bit & 0x04 ); | ||||||
7623 | fHyphCapitals = 0 != ( a8Bit & 0x08 ); | ||||||
7624 | fAutoHyphen = 0 != ( a8Bit & 0x10 ); | ||||||
7625 | fFormNoFields = 0 != ( a8Bit & 0x20 ); | ||||||
7626 | fLinkStyles = 0 != ( a8Bit & 0x40 ); | ||||||
7627 | fRevMarking = 0 != ( a8Bit & 0x80 ); | ||||||
7628 | |||||||
7629 | a8Bit = Get_Byte( pData ); // 6 0x06 | ||||||
7630 | fBackup = 0 != ( a8Bit & 0x01 ); | ||||||
7631 | fExactCWords = 0 != ( a8Bit & 0x02 ); | ||||||
7632 | fPagHidden = 0 != ( a8Bit & 0x04 ); | ||||||
7633 | fPagResults = 0 != ( a8Bit & 0x08 ); | ||||||
7634 | fLockAtn = 0 != ( a8Bit & 0x10 ); | ||||||
7635 | fMirrorMargins = 0 != ( a8Bit & 0x20 ); | ||||||
7636 | fReadOnlyRecommended = 0 != ( a8Bit & 0x40 ); | ||||||
7637 | fDfltTrueType = 0 != ( a8Bit & 0x80 ); | ||||||
7638 | |||||||
7639 | a8Bit = Get_Byte( pData ); // 7 0x07 | ||||||
7640 | fPagSuppressTopSpacing = 0 != ( a8Bit & 0x01 ); | ||||||
7641 | fProtEnabled = 0 != ( a8Bit & 0x02 ); | ||||||
7642 | fDispFormFieldSel = 0 != ( a8Bit & 0x04 ); | ||||||
7643 | fRMView = 0 != ( a8Bit & 0x08 ); | ||||||
7644 | fRMPrint = 0 != ( a8Bit & 0x10 ); | ||||||
7645 | fWriteReservation = 0 != ( a8Bit & 0x20 ); | ||||||
7646 | fLockRev = 0 != ( a8Bit & 0x40 ); | ||||||
7647 | fEmbedFonts = 0 != ( a8Bit & 0x80 ); | ||||||
7648 | |||||||
7649 | a8Bit = Get_Byte( pData ); // 8 0x08 | ||||||
7650 | copts_fNoTabForInd = 0 != ( a8Bit & 0x01 ); | ||||||
7651 | copts_fNoSpaceRaiseLower = 0 != ( a8Bit & 0x02 ); | ||||||
7652 | copts_fSupressSpbfAfterPgBrk = 0 != ( a8Bit & 0x04 ); | ||||||
7653 | copts_fWrapTrailSpaces = 0 != ( a8Bit & 0x08 ); | ||||||
7654 | copts_fMapPrintTextColor = 0 != ( a8Bit & 0x10 ); | ||||||
7655 | copts_fNoColumnBalance = 0 != ( a8Bit & 0x20 ); | ||||||
7656 | copts_fConvMailMergeEsc = 0 != ( a8Bit & 0x40 ); | ||||||
7657 | copts_fSupressTopSpacing = 0 != ( a8Bit & 0x80 ); | ||||||
7658 | |||||||
7659 | a8Bit = Get_Byte( pData ); // 9 0x09 | ||||||
7660 | copts_fOrigWordTableRules = 0 != ( a8Bit & 0x01 ); | ||||||
7661 | copts_fTransparentMetafiles = 0 != ( a8Bit & 0x02 ); | ||||||
7662 | copts_fShowBreaksInFrames = 0 != ( a8Bit & 0x04 ); | ||||||
7663 | copts_fSwapBordersFacingPgs = 0 != ( a8Bit & 0x08 ); | ||||||
7664 | copts_fExpShRtn = 0 != ( a8Bit & 0x20 ); // #i56856# | ||||||
7665 | |||||||
7666 | dxaTab = Get_Short( pData ); // 10 0x0a | ||||||
7667 | wSpare = Get_UShort( pData ); // 12 0x0c | ||||||
7668 | dxaHotZ = Get_UShort( pData ); // 14 0x0e | ||||||
7669 | cConsecHypLim = Get_UShort( pData ); // 16 0x10 | ||||||
7670 | wSpare2 = Get_UShort( pData ); // 18 0x12 | ||||||
7671 | dttmCreated = Get_Long( pData ); // 20 0x14 | ||||||
7672 | dttmRevised = Get_Long( pData ); // 24 0x18 | ||||||
7673 | dttmLastPrint = Get_Long( pData ); // 28 0x1c | ||||||
7674 | nRevision = Get_Short( pData ); // 32 0x20 | ||||||
7675 | tmEdited = Get_Long( pData ); // 34 0x22 | ||||||
7676 | cWords = Get_Long( pData ); // 38 0x26 | ||||||
7677 | cCh = Get_Long( pData ); // 42 0x2a | ||||||
7678 | cPg = Get_Short( pData ); // 46 0x2e | ||||||
7679 | cParas = Get_Long( pData ); // 48 0x30 | ||||||
7680 | |||||||
7681 | a16Bit = Get_UShort( pData ); // 52 0x34 | ||||||
7682 | rncEdn = a16Bit & 0x0003 ; | ||||||
7683 | nEdn = ( a16Bit & ~0x0003 ) >> 2; | ||||||
7684 | |||||||
7685 | a16Bit = Get_UShort( pData ); // 54 0x36 | ||||||
7686 | epc = a16Bit & 0x0003 ; | ||||||
7687 | nfcFootnoteRef = ( a16Bit & 0x003c ) >> 2; | ||||||
7688 | nfcEdnRef = ( a16Bit & 0x03c0 ) >> 6; | ||||||
7689 | fPrintFormData = 0 != ( a16Bit & 0x0400 ); | ||||||
7690 | fSaveFormData = 0 != ( a16Bit & 0x0800 ); | ||||||
7691 | fShadeFormData = 0 != ( a16Bit & 0x1000 ); | ||||||
7692 | fWCFootnoteEdn = 0 != ( a16Bit & 0x8000 ); | ||||||
7693 | |||||||
7694 | cLines = Get_Long( pData ); // 56 0x38 | ||||||
7695 | cWordsFootnoteEnd = Get_Long( pData ); // 60 0x3c | ||||||
7696 | cChFootnoteEdn = Get_Long( pData ); // 64 0x40 | ||||||
7697 | cPgFootnoteEdn = Get_Short( pData ); // 68 0x44 | ||||||
7698 | cParasFootnoteEdn = Get_Long( pData ); // 70 0x46 | ||||||
7699 | cLinesFootnoteEdn = Get_Long( pData ); // 74 0x4a | ||||||
7700 | lKeyProtDoc = Get_Long( pData ); // 78 0x4e | ||||||
7701 | |||||||
7702 | a16Bit = Get_UShort( pData ); // 82 0x52 | ||||||
7703 | wvkSaved = a16Bit & 0x0007 ; | ||||||
7704 | wScaleSaved = ( a16Bit & 0x0ff8 ) >> 3 ; | ||||||
7705 | zkSaved = ( a16Bit & 0x3000 ) >> 12; | ||||||
7706 | fRotateFontW6 = ( a16Bit & 0x4000 ) >> 14; | ||||||
7707 | iGutterPos = ( a16Bit & 0x8000 ) >> 15; | ||||||
7708 | |||||||
7709 | if (nFib >= 103) // Word 6/32bit, 95, 97, 2000, 2002, 2003, 2007 | ||||||
7710 | { | ||||||
7711 | a32Bit = Get_ULong( pData ); // 84 0x54 | ||||||
7712 | SetCompatibilityOptions(a32Bit); | ||||||
7713 | } | ||||||
7714 | |||||||
7715 | //#i22436#, for all WW7- documents | ||||||
7716 | if (nFib <= 104) // Word 95 | ||||||
7717 | fUsePrinterMetrics = true; | ||||||
7718 | |||||||
7719 | if (nFib > 105) // Word 97, 2000, 2002, 2003, 2007 | ||||||
7720 | { | ||||||
7721 | adt = Get_Short( pData ); // 88 0x58 | ||||||
7722 | |||||||
7723 | doptypography.ReadFromMem(pData); // 90 0x5a | ||||||
7724 | |||||||
7725 | memcpy( &dogrid, pData, sizeof( WW8_DOGRID )); // 400 0x190 | ||||||
7726 | pData += sizeof( WW8_DOGRID ); | ||||||
7727 | |||||||
7728 | a16Bit = Get_UShort( pData ); // 410 0x19a | ||||||
7729 | // the following 9 bit are uninteresting | ||||||
7730 | fHtmlDoc = ( a16Bit & 0x0200 ) >> 9 ; | ||||||
7731 | fSnapBorder = ( a16Bit & 0x0800 ) >> 11 ; | ||||||
7732 | fIncludeHeader = ( a16Bit & 0x1000 ) >> 12 ; | ||||||
7733 | fIncludeFooter = ( a16Bit & 0x2000 ) >> 13 ; | ||||||
7734 | fForcePageSizePag = ( a16Bit & 0x4000 ) >> 14 ; | ||||||
7735 | fMinFontSizePag = ( a16Bit & 0x8000 ) >> 15 ; | ||||||
7736 | |||||||
7737 | a16Bit = Get_UShort( pData ); // 412 0x19c | ||||||
7738 | fHaveVersions = 0 != ( a16Bit & 0x0001 ); | ||||||
7739 | fAutoVersion = 0 != ( a16Bit & 0x0002 ); | ||||||
7740 | |||||||
7741 | pData += 12; // 414 0x19e | ||||||
7742 | |||||||
7743 | cChWS = Get_Long( pData ); // 426 0x1aa | ||||||
7744 | cChWSFootnoteEdn = Get_Long( pData ); // 430 0x1ae | ||||||
7745 | grfDocEvents = Get_Long( pData ); // 434 0x1b2 | ||||||
7746 | |||||||
7747 | pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc | ||||||
7748 | |||||||
7749 | cDBC = Get_Long( pData ); // 480 0x1e0 | ||||||
7750 | cDBCFootnoteEdn = Get_Long( pData ); // 484 0x1e4 | ||||||
7751 | |||||||
7752 | pData += 1 * sizeof( sal_Int32); // 488 0x1e8 | ||||||
7753 | |||||||
7754 | nfcFootnoteRef = Get_Short( pData ); // 492 0x1ec | ||||||
7755 | nfcEdnRef = Get_Short( pData ); // 494 0x1ee | ||||||
7756 | hpsZoomFontPag = Get_Short( pData ); // 496 0x1f0 | ||||||
7757 | dywDispPag = Get_Short( pData ); // 498 0x1f2 | ||||||
7758 | |||||||
7759 | if (nRead >= 516) | ||||||
7760 | { | ||||||
7761 | //500 -> 508, Appear to be repeated here in 2000+ | ||||||
7762 | pData += 8; // 500 0x1f4 | ||||||
7763 | a32Bit = Get_Long( pData ); // 508 0x1fc | ||||||
7764 | SetCompatibilityOptions(a32Bit); | ||||||
7765 | a32Bit = Get_Long( pData ); // 512 0x200 | ||||||
7766 | |||||||
7767 | // i#78591# | ||||||
7768 | SetCompatibilityOptions2(a32Bit); | ||||||
7769 | } | ||||||
7770 | if (nRead >= 550) | ||||||
7771 | { | ||||||
7772 | pData += 32; | ||||||
7773 | a16Bit = Get_UShort( pData ); | ||||||
7774 | fDoNotEmbedSystemFont = ( a16Bit & 0x0001 ); | ||||||
7775 | fWordCompat = ( a16Bit & 0x0002 ) >> 1; | ||||||
7776 | fLiveRecover = ( a16Bit & 0x0004 ) >> 2; | ||||||
7777 | fEmbedFactoids = ( a16Bit & 0x0008 ) >> 3; | ||||||
7778 | fFactoidXML = ( a16Bit & 0x00010 ) >> 4; | ||||||
7779 | fFactoidAllDone = ( a16Bit & 0x0020 ) >> 5; | ||||||
7780 | fFolioPrint = ( a16Bit & 0x0040 ) >> 6; | ||||||
7781 | fReverseFolio = ( a16Bit & 0x0080 ) >> 7; | ||||||
7782 | iTextLineEnding = ( a16Bit & 0x0700 ) >> 8; | ||||||
7783 | fHideFcc = ( a16Bit & 0x0800 ) >> 11; | ||||||
7784 | fAcetateShowMarkup = ( a16Bit & 0x1000 ) >> 12; | ||||||
7785 | fAcetateShowAtn = ( a16Bit & 0x2000 ) >> 13; | ||||||
7786 | fAcetateShowInsDel = ( a16Bit & 0x4000 ) >> 14; | ||||||
7787 | fAcetateShowProps = ( a16Bit & 0x8000 ) >> 15; | ||||||
7788 | } | ||||||
7789 | if (nRead >= 600) | ||||||
7790 | { | ||||||
7791 | pData += 48; | ||||||
7792 | a16Bit = Get_Short(pData); | ||||||
7793 | fUseBackGroundInAllmodes = (a16Bit & 0x0080) >> 7; | ||||||
7794 | } | ||||||
7795 | } | ||||||
7796 | } | ||||||
7797 | } | ||||||
7798 | |||||||
7799 | WW8Dop::WW8Dop(): | ||||||
7800 | fFacingPages(false), fWidowControl(true), fPMHMainDoc(false), grfSuppression(0), fpc(1), | ||||||
7801 | grpfIhdt(0), rncFootnote(0), nFootnote(1), fOutlineDirtySave(true), fOnlyMacPics(false), | ||||||
7802 | fOnlyWinPics(false), fLabelDoc(false), fHyphCapitals(true), fAutoHyphen(false), | ||||||
7803 | fFormNoFields(false), fLinkStyles(false), fRevMarking(false), fBackup(true), | ||||||
7804 | fExactCWords(false), fPagHidden(true), fPagResults(true), fLockAtn(false), | ||||||
7805 | fMirrorMargins(false), fReadOnlyRecommended(false), fDfltTrueType(true), | ||||||
7806 | fPagSuppressTopSpacing(false), fProtEnabled(false), fDispFormFieldSel(false), fRMView(true), | ||||||
7807 | fRMPrint(true), fWriteReservation(false), fLockRev(false), fEmbedFonts(false), | ||||||
7808 | copts_fNoTabForInd(false), copts_fNoSpaceRaiseLower(false), copts_fSupressSpbfAfterPgBrk(false), | ||||||
7809 | copts_fWrapTrailSpaces(false), copts_fMapPrintTextColor(false), copts_fNoColumnBalance(false), | ||||||
7810 | copts_fConvMailMergeEsc(false), copts_fSupressTopSpacing(false), | ||||||
7811 | copts_fOrigWordTableRules(false), copts_fTransparentMetafiles(false), | ||||||
7812 | copts_fShowBreaksInFrames(false), copts_fSwapBordersFacingPgs(false), copts_fExpShRtn(false), | ||||||
7813 | dxaTab(0x2d0), dxaHotZ(0x168), nRevision(1), | ||||||
7814 | rncEdn(0), nEdn(1), epc(3), fPrintFormData(false), fSaveFormData(false), fShadeFormData(true), | ||||||
7815 | fWCFootnoteEdn(false), wvkSaved(2), wScaleSaved(100), zkSaved(0), fRotateFontW6(false), | ||||||
7816 | iGutterPos(false), fNoTabForInd(false), fNoSpaceRaiseLower(false), | ||||||
7817 | fSupressSpbfAfterPageBreak(false), fWrapTrailSpaces(false), fMapPrintTextColor(false), | ||||||
7818 | fNoColumnBalance(false), fConvMailMergeEsc(false), fSupressTopSpacing(false), | ||||||
7819 | fOrigWordTableRules(false), fTransparentMetafiles(false), fShowBreaksInFrames(false), | ||||||
7820 | fSwapBordersFacingPgs(false), fCompatibilityOptions_Unknown1_13(false), fExpShRtn(false), | ||||||
7821 | fCompatibilityOptions_Unknown1_15(false), fCompatibilityOptions_Unknown1_16(false), | ||||||
7822 | fSuppressTopSpacingMac5(false), fTruncDxaExpand(false), fPrintBodyBeforeHdr(false), | ||||||
7823 | fNoLeading(true), fCompatibilityOptions_Unknown1_21(false), fMWSmallCaps(false), | ||||||
7824 | fCompatibilityOptions_Unknown1_23(false), fCompatibilityOptions_Unknown1_24(false), | ||||||
7825 | fCompatibilityOptions_Unknown1_25(false), fCompatibilityOptions_Unknown1_26(false), | ||||||
7826 | fCompatibilityOptions_Unknown1_27(false), fCompatibilityOptions_Unknown1_28(false), | ||||||
7827 | fCompatibilityOptions_Unknown1_29(false), fCompatibilityOptions_Unknown1_30(false), | ||||||
7828 | fCompatibilityOptions_Unknown1_31(false), fUsePrinterMetrics(true), lvl(9), fHtmlDoc(false), | ||||||
7829 | fSnapBorder(false), fIncludeHeader(true), fIncludeFooter(true), fForcePageSizePag(false), | ||||||
7830 | fMinFontSizePag(false), fHaveVersions(false), fAutoVersion(false), | ||||||
7831 | cChWS(0), cChWSFootnoteEdn(0), cDBC(0), cDBCFootnoteEdn(0), nfcEdnRef(2), | ||||||
7832 | fCompatibilityOptions_Unknown2_1(false), fCompatibilityOptions_Unknown2_2(false), | ||||||
7833 | fDontUseHTMLAutoSpacing(false), fCompatibilityOptions_Unknown2_4(false), | ||||||
7834 | fCompatibilityOptions_Unknown2_5(false), fCompatibilityOptions_Unknown2_6(false), | ||||||
7835 | fCompatibilityOptions_Unknown2_7(false), fCompatibilityOptions_Unknown2_8(false), | ||||||
7836 | fCompatibilityOptions_Unknown2_9(false), fCompatibilityOptions_Unknown2_10(false), | ||||||
7837 | fCompatibilityOptions_Unknown2_11(false), fCompatibilityOptions_Unknown2_12(false), | ||||||
7838 | fCompatibilityOptions_Unknown2_13(false), fCompatibilityOptions_Unknown2_14(false), | ||||||
7839 | fCompatibilityOptions_Unknown2_15(false), fCompatibilityOptions_Unknown2_16(false), | ||||||
7840 | fCompatibilityOptions_Unknown2_17(false), fCompatibilityOptions_Unknown2_18(false), | ||||||
7841 | fCompatibilityOptions_Unknown2_19(false), fCompatibilityOptions_Unknown2_20(false), | ||||||
7842 | fCompatibilityOptions_Unknown2_21(false), fCompatibilityOptions_Unknown2_22(false), | ||||||
7843 | fCompatibilityOptions_Unknown2_23(false), fCompatibilityOptions_Unknown2_24(false), | ||||||
7844 | fCompatibilityOptions_Unknown2_25(false), fCompatibilityOptions_Unknown2_26(false), | ||||||
7845 | fCompatibilityOptions_Unknown2_27(false), fCompatibilityOptions_Unknown2_28(false), | ||||||
7846 | fCompatibilityOptions_Unknown2_29(false), fCompatibilityOptions_Unknown2_30(false), | ||||||
7847 | fCompatibilityOptions_Unknown2_31(false), fCompatibilityOptions_Unknown2_32(false), | ||||||
7848 | fUnknown3(0), fUseBackGroundInAllmodes(false), fDoNotEmbedSystemFont(false), fWordCompat(false), | ||||||
7849 | fLiveRecover(false), fEmbedFactoids(false), fFactoidXML(false), fFactoidAllDone(false), | ||||||
7850 | fFolioPrint(false), fReverseFolio(false), iTextLineEnding(0), fHideFcc(false), | ||||||
7851 | fAcetateShowMarkup(false), fAcetateShowAtn(true), fAcetateShowInsDel(false), | ||||||
7852 | fAcetateShowProps(false) | ||||||
7853 | // in C++20 with P06831R1 "Default member initializers for bit-fields (revision 1)", the | ||||||
7854 | // above bit-field member initializations can be moved to the class definition | ||||||
7855 | { | ||||||
7856 | /* | ||||||
7857 | Writer acts like this all the time at the moment, ideally we need an | ||||||
7858 | option for these two as well to import word docs that are not like | ||||||
7859 | this by default | ||||||
7860 | */ | ||||||
7861 | // put in initialization list | ||||||
7862 | // fNoLeading = true; | ||||||
7863 | //fUsePrinterMetrics = true; | ||||||
7864 | } | ||||||
7865 | |||||||
7866 | void WW8Dop::SetCompatibilityOptions(sal_uInt32 a32Bit) | ||||||
7867 | { | ||||||
7868 | fNoTabForInd = ( a32Bit & 0x00000001 ) ; | ||||||
7869 | fNoSpaceRaiseLower = ( a32Bit & 0x00000002 ) >> 1 ; | ||||||
7870 | fSupressSpbfAfterPageBreak = ( a32Bit & 0x00000004 ) >> 2 ; | ||||||
7871 | fWrapTrailSpaces = ( a32Bit & 0x00000008 ) >> 3 ; | ||||||
7872 | fMapPrintTextColor = ( a32Bit & 0x00000010 ) >> 4 ; | ||||||
7873 | fNoColumnBalance = ( a32Bit & 0x00000020 ) >> 5 ; | ||||||
7874 | fConvMailMergeEsc = ( a32Bit & 0x00000040 ) >> 6 ; | ||||||
7875 | fSupressTopSpacing = ( a32Bit & 0x00000080 ) >> 7 ; | ||||||
7876 | fOrigWordTableRules = ( a32Bit & 0x00000100 ) >> 8 ; | ||||||
7877 | fTransparentMetafiles = ( a32Bit & 0x00000200 ) >> 9 ; | ||||||
7878 | fShowBreaksInFrames = ( a32Bit & 0x00000400 ) >> 10 ; | ||||||
7879 | fSwapBordersFacingPgs = ( a32Bit & 0x00000800 ) >> 11 ; | ||||||
7880 | fCompatibilityOptions_Unknown1_13 = ( a32Bit & 0x00001000 ) >> 12 ; | ||||||
7881 | fExpShRtn = ( a32Bit & 0x00002000 ) >> 13 ; // #i56856# | ||||||
7882 | fCompatibilityOptions_Unknown1_15 = ( a32Bit & 0x00004000 ) >> 14 ; | ||||||
7883 | fCompatibilityOptions_Unknown1_16 = ( a32Bit & 0x00008000 ) >> 15 ; | ||||||
7884 | fSuppressTopSpacingMac5 = ( a32Bit & 0x00010000 ) >> 16 ; | ||||||
7885 | fTruncDxaExpand = ( a32Bit & 0x00020000 ) >> 17 ; | ||||||
7886 | fPrintBodyBeforeHdr = ( a32Bit & 0x00040000 ) >> 18 ; | ||||||
7887 | fNoLeading = ( a32Bit & 0x00080000 ) >> 19 ; | ||||||
7888 | fCompatibilityOptions_Unknown1_21 = ( a32Bit & 0x00100000 ) >> 20 ; | ||||||
7889 | fMWSmallCaps = ( a32Bit & 0x00200000 ) >> 21 ; | ||||||
7890 | fCompatibilityOptions_Unknown1_23 = ( a32Bit & 0x00400000 ) >> 22 ; | ||||||
7891 | fCompatibilityOptions_Unknown1_24 = ( a32Bit & 0x00800800 ) >> 23 ; | ||||||
7892 | fCompatibilityOptions_Unknown1_25 = ( a32Bit & 0x01000000 ) >> 24 ; | ||||||
7893 | fCompatibilityOptions_Unknown1_26 = ( a32Bit & 0x02000000 ) >> 25 ; | ||||||
7894 | fCompatibilityOptions_Unknown1_27 = ( a32Bit & 0x04000000 ) >> 26 ; | ||||||
7895 | fCompatibilityOptions_Unknown1_28 = ( a32Bit & 0x08000000 ) >> 27 ; | ||||||
7896 | fCompatibilityOptions_Unknown1_29 = ( a32Bit & 0x10000000 ) >> 28 ; | ||||||
7897 | fCompatibilityOptions_Unknown1_30 = ( a32Bit & 0x20000000 ) >> 29 ; | ||||||
7898 | fCompatibilityOptions_Unknown1_31 = ( a32Bit & 0x40000000 ) >> 30 ; | ||||||
7899 | |||||||
7900 | fUsePrinterMetrics = ( a32Bit & 0x80000000 ) >> 31 ; | ||||||
7901 | } | ||||||
7902 | |||||||
7903 | sal_uInt32 WW8Dop::GetCompatibilityOptions() const | ||||||
7904 | { | ||||||
7905 | sal_uInt32 a32Bit = 0; | ||||||
7906 | if (fNoTabForInd) a32Bit |= 0x00000001; | ||||||
7907 | if (fNoSpaceRaiseLower) a32Bit |= 0x00000002; | ||||||
7908 | if (fSupressSpbfAfterPageBreak) a32Bit |= 0x00000004; | ||||||
7909 | if (fWrapTrailSpaces) a32Bit |= 0x00000008; | ||||||
7910 | if (fMapPrintTextColor) a32Bit |= 0x00000010; | ||||||
7911 | if (fNoColumnBalance) a32Bit |= 0x00000020; | ||||||
7912 | if (fConvMailMergeEsc) a32Bit |= 0x00000040; | ||||||
7913 | if (fSupressTopSpacing) a32Bit |= 0x00000080; | ||||||
7914 | if (fOrigWordTableRules) a32Bit |= 0x00000100; | ||||||
7915 | if (fTransparentMetafiles) a32Bit |= 0x00000200; | ||||||
7916 | if (fShowBreaksInFrames) a32Bit |= 0x00000400; | ||||||
7917 | if (fSwapBordersFacingPgs) a32Bit |= 0x00000800; | ||||||
7918 | if (fCompatibilityOptions_Unknown1_13) a32Bit |= 0x00001000; | ||||||
7919 | if (fExpShRtn) a32Bit |= 0x00002000; // #i56856# | ||||||
7920 | if (fCompatibilityOptions_Unknown1_15) a32Bit |= 0x00004000; | ||||||
7921 | if (fCompatibilityOptions_Unknown1_16) a32Bit |= 0x00008000; | ||||||
7922 | if (fSuppressTopSpacingMac5) a32Bit |= 0x00010000; | ||||||
7923 | if (fTruncDxaExpand) a32Bit |= 0x00020000; | ||||||
7924 | if (fPrintBodyBeforeHdr) a32Bit |= 0x00040000; | ||||||
7925 | if (fNoLeading) a32Bit |= 0x00080000; | ||||||
7926 | if (fCompatibilityOptions_Unknown1_21) a32Bit |= 0x00100000; | ||||||
7927 | if (fMWSmallCaps) a32Bit |= 0x00200000; | ||||||
7928 | if (fCompatibilityOptions_Unknown1_23) a32Bit |= 0x00400000; | ||||||
7929 | if (fCompatibilityOptions_Unknown1_24) a32Bit |= 0x00800000; | ||||||
7930 | if (fCompatibilityOptions_Unknown1_25) a32Bit |= 0x01000000; | ||||||
7931 | if (fCompatibilityOptions_Unknown1_26) a32Bit |= 0x02000000; | ||||||
7932 | if (fCompatibilityOptions_Unknown1_27) a32Bit |= 0x04000000; | ||||||
7933 | if (fCompatibilityOptions_Unknown1_28) a32Bit |= 0x08000000; | ||||||
7934 | if (fCompatibilityOptions_Unknown1_29) a32Bit |= 0x10000000; | ||||||
7935 | if (fCompatibilityOptions_Unknown1_30) a32Bit |= 0x20000000; | ||||||
7936 | if (fCompatibilityOptions_Unknown1_31) a32Bit |= 0x40000000; | ||||||
7937 | if (fUsePrinterMetrics) a32Bit |= 0x80000000; | ||||||
7938 | return a32Bit; | ||||||
7939 | } | ||||||
7940 | |||||||
7941 | // i#78591# | ||||||
7942 | void WW8Dop::SetCompatibilityOptions2(sal_uInt32 a32Bit) | ||||||
7943 | { | ||||||
7944 | fCompatibilityOptions_Unknown2_1 = ( a32Bit & 0x00000001 ); | ||||||
7945 | fCompatibilityOptions_Unknown2_2 = ( a32Bit & 0x00000002 ) >> 1 ; | ||||||
7946 | fDontUseHTMLAutoSpacing = ( a32Bit & 0x00000004 ) >> 2 ; | ||||||
7947 | fCompatibilityOptions_Unknown2_4 = ( a32Bit & 0x00000008 ) >> 3 ; | ||||||
7948 | fCompatibilityOptions_Unknown2_5 = ( a32Bit & 0x00000010 ) >> 4 ; | ||||||
7949 | fCompatibilityOptions_Unknown2_6 = ( a32Bit & 0x00000020 ) >> 5 ; | ||||||
7950 | fCompatibilityOptions_Unknown2_7 = ( a32Bit & 0x00000040 ) >> 6 ; | ||||||
7951 | fCompatibilityOptions_Unknown2_8 = ( a32Bit & 0x00000080 ) >> 7 ; | ||||||
7952 | fCompatibilityOptions_Unknown2_9 = ( a32Bit & 0x00000100 ) >> 8 ; | ||||||
7953 | fCompatibilityOptions_Unknown2_10 = ( a32Bit & 0x00000200 ) >> 9 ; | ||||||
7954 | fCompatibilityOptions_Unknown2_11 = ( a32Bit & 0x00000400 ) >> 10 ; | ||||||
7955 | fCompatibilityOptions_Unknown2_12 = ( a32Bit & 0x00000800 ) >> 11 ; | ||||||
7956 | fCompatibilityOptions_Unknown2_13 = ( a32Bit & 0x00001000 ) >> 12 ; | ||||||
7957 | fCompatibilityOptions_Unknown2_14 = ( a32Bit & 0x00002000 ) >> 13 ; | ||||||
7958 | fCompatibilityOptions_Unknown2_15 = ( a32Bit & 0x00004000 ) >> 14 ; | ||||||
7959 | fCompatibilityOptions_Unknown2_16 = ( a32Bit & 0x00008000 ) >> 15 ; | ||||||
7960 | fCompatibilityOptions_Unknown2_17 = ( a32Bit & 0x00010000 ) >> 16 ; | ||||||
7961 | fCompatibilityOptions_Unknown2_18 = ( a32Bit & 0x00020000 ) >> 17 ; | ||||||
7962 | fCompatibilityOptions_Unknown2_19 = ( a32Bit & 0x00040000 ) >> 18 ; | ||||||
7963 | fCompatibilityOptions_Unknown2_20 = ( a32Bit & 0x00080000 ) >> 19 ; | ||||||
7964 | fCompatibilityOptions_Unknown2_21 = ( a32Bit & 0x00100000 ) >> 20 ; | ||||||
7965 | fCompatibilityOptions_Unknown2_22 = ( a32Bit & 0x00200000 ) >> 21 ; | ||||||
7966 | fCompatibilityOptions_Unknown2_23 = ( a32Bit & 0x00400000 ) >> 22 ; | ||||||
7967 | fCompatibilityOptions_Unknown2_24 = ( a32Bit & 0x00800800 ) >> 23 ; | ||||||
7968 | fCompatibilityOptions_Unknown2_25 = ( a32Bit & 0x01000800 ) >> 24 ; | ||||||
7969 | fCompatibilityOptions_Unknown2_26 = ( a32Bit & 0x02000800 ) >> 25 ; | ||||||
7970 | fCompatibilityOptions_Unknown2_27 = ( a32Bit & 0x04000800 ) >> 26 ; | ||||||
7971 | fCompatibilityOptions_Unknown2_28 = ( a32Bit & 0x08000800 ) >> 27 ; | ||||||
7972 | fCompatibilityOptions_Unknown2_29 = ( a32Bit & 0x10000800 ) >> 28 ; | ||||||
7973 | fCompatibilityOptions_Unknown2_30 = ( a32Bit & 0x20000800 ) >> 29 ; | ||||||
7974 | fCompatibilityOptions_Unknown2_31 = ( a32Bit & 0x40000800 ) >> 30 ; | ||||||
7975 | fCompatibilityOptions_Unknown2_32 = ( a32Bit & 0x80000000 ) >> 31 ; | ||||||
7976 | } | ||||||
7977 | |||||||
7978 | sal_uInt32 WW8Dop::GetCompatibilityOptions2() const | ||||||
7979 | { | ||||||
7980 | sal_uInt32 a32Bit = 0; | ||||||
7981 | if (fCompatibilityOptions_Unknown2_1) a32Bit |= 0x00000001; | ||||||
7982 | if (fCompatibilityOptions_Unknown2_2) a32Bit |= 0x00000002; | ||||||
7983 | if (fDontUseHTMLAutoSpacing) a32Bit |= 0x00000004; | ||||||
7984 | if (fCompatibilityOptions_Unknown2_4) a32Bit |= 0x00000008; | ||||||
7985 | if (fCompatibilityOptions_Unknown2_5) a32Bit |= 0x00000010; | ||||||
7986 | if (fCompatibilityOptions_Unknown2_6) a32Bit |= 0x00000020; | ||||||
7987 | if (fCompatibilityOptions_Unknown2_7) a32Bit |= 0x00000040; | ||||||
7988 | if (fCompatibilityOptions_Unknown2_8) a32Bit |= 0x00000080; | ||||||
7989 | if (fCompatibilityOptions_Unknown2_9) a32Bit |= 0x00000100; | ||||||
7990 | if (fCompatibilityOptions_Unknown2_10) a32Bit |= 0x00000200; | ||||||
7991 | if (fCompatibilityOptions_Unknown2_11) a32Bit |= 0x00000400; | ||||||
7992 | if (fCompatibilityOptions_Unknown2_12) a32Bit |= 0x00000800; | ||||||
7993 | if (fCompatibilityOptions_Unknown2_13) a32Bit |= 0x00001000; | ||||||
7994 | //#i42909# set thai "line breaking rules" compatibility option | ||||||
7995 | // pflin, wonder whether bUseThaiLineBreakingRules is correct | ||||||
7996 | // when importing word document. | ||||||
7997 | if (bUseThaiLineBreakingRules) a32Bit |= 0x00002000; | ||||||
7998 | else if (fCompatibilityOptions_Unknown2_14) a32Bit |= 0x00002000; | ||||||
7999 | if (fCompatibilityOptions_Unknown2_15) a32Bit |= 0x00004000; | ||||||
8000 | if (fCompatibilityOptions_Unknown2_16) a32Bit |= 0x00008000; | ||||||
8001 | if (fCompatibilityOptions_Unknown2_17) a32Bit |= 0x00010000; | ||||||
8002 | if (fCompatibilityOptions_Unknown2_18) a32Bit |= 0x00020000; | ||||||
8003 | if (fCompatibilityOptions_Unknown2_19) a32Bit |= 0x00040000; | ||||||
8004 | if (fCompatibilityOptions_Unknown2_20) a32Bit |= 0x00080000; | ||||||
8005 | if (fCompatibilityOptions_Unknown2_21) a32Bit |= 0x00100000; | ||||||
8006 | if (fCompatibilityOptions_Unknown2_22) a32Bit |= 0x00200000; | ||||||
8007 | if (fCompatibilityOptions_Unknown2_23) a32Bit |= 0x00400000; | ||||||
8008 | if (fCompatibilityOptions_Unknown2_24) a32Bit |= 0x00800000; | ||||||
8009 | if (fCompatibilityOptions_Unknown2_25) a32Bit |= 0x01000000; | ||||||
8010 | if (fCompatibilityOptions_Unknown2_26) a32Bit |= 0x02000000; | ||||||
8011 | if (fCompatibilityOptions_Unknown2_27) a32Bit |= 0x04000000; | ||||||
8012 | if (fCompatibilityOptions_Unknown2_28) a32Bit |= 0x08000000; | ||||||
8013 | if (fCompatibilityOptions_Unknown2_29) a32Bit |= 0x10000000; | ||||||
8014 | if (fCompatibilityOptions_Unknown2_30) a32Bit |= 0x20000000; | ||||||
8015 | if (fCompatibilityOptions_Unknown2_31) a32Bit |= 0x40000000; | ||||||
8016 | if (fCompatibilityOptions_Unknown2_32) a32Bit |= 0x80000000; | ||||||
8017 | return a32Bit; | ||||||
8018 | } | ||||||
8019 | |||||||
8020 | void WW8Dop::Write(SvStream& rStrm, WW8Fib& rFib) const | ||||||
8021 | { | ||||||
8022 | const int nMaxDopLen = 610; | ||||||
8023 | sal_uInt32 nLen = 8 == rFib.m_nVersion ? nMaxDopLen : 84; | ||||||
8024 | rFib.m_fcDop = rStrm.Tell(); | ||||||
8025 | rFib.m_lcbDop = nLen; | ||||||
8026 | |||||||
8027 | sal_uInt8 aData[ nMaxDopLen ] = {}; | ||||||
8028 | sal_uInt8* pData = aData; | ||||||
8029 | |||||||
8030 | // analyse the data | ||||||
8031 | sal_uInt16 a16Bit; | ||||||
8032 | sal_uInt8 a8Bit; | ||||||
8033 | |||||||
8034 | a16Bit = 0; // 0 0x00 | ||||||
8035 | if (fFacingPages) | ||||||
8036 | a16Bit |= 0x0001; | ||||||
8037 | if (fWidowControl) | ||||||
8038 | a16Bit |= 0x0002; | ||||||
8039 | if (fPMHMainDoc) | ||||||
8040 | a16Bit |= 0x0004; | ||||||
8041 | a16Bit |= ( 0x0018 & (grfSuppression << 3)); | ||||||
8042 | a16Bit |= ( 0x0060 & (fpc << 5)); | ||||||
8043 | a16Bit |= ( 0xff00 & (grpfIhdt << 8)); | ||||||
8044 | Set_UInt16( pData, a16Bit ); | ||||||
8045 | |||||||
8046 | a16Bit = 0; // 2 0x02 | ||||||
8047 | a16Bit |= ( 0x0003 & rncFootnote ); | ||||||
8048 | a16Bit |= ( ~0x0003 & (nFootnote << 2)); | ||||||
8049 | Set_UInt16( pData, a16Bit ); | ||||||
8050 | |||||||
8051 | a8Bit = 0; // 4 0x04 | ||||||
8052 | if( fOutlineDirtySave ) a8Bit |= 0x01; | ||||||
8053 | Set_UInt8( pData, a8Bit ); | ||||||
8054 | |||||||
8055 | a8Bit = 0; // 5 0x05 | ||||||
8056 | if( fOnlyMacPics ) a8Bit |= 0x01; | ||||||
8057 | if( fOnlyWinPics ) a8Bit |= 0x02; | ||||||
8058 | if( fLabelDoc ) a8Bit |= 0x04; | ||||||
8059 | if( fHyphCapitals ) a8Bit |= 0x08; | ||||||
8060 | if( fAutoHyphen ) a8Bit |= 0x10; | ||||||
8061 | if( fFormNoFields ) a8Bit |= 0x20; | ||||||
8062 | if( fLinkStyles ) a8Bit |= 0x40; | ||||||
8063 | if( fRevMarking ) a8Bit |= 0x80; | ||||||
8064 | Set_UInt8( pData, a8Bit ); | ||||||
8065 | |||||||
8066 | a8Bit = 0; // 6 0x06 | ||||||
8067 | if( fBackup ) a8Bit |= 0x01; | ||||||
8068 | if( fExactCWords ) a8Bit |= 0x02; | ||||||
8069 | if( fPagHidden ) a8Bit |= 0x04; | ||||||
8070 | if( fPagResults ) a8Bit |= 0x08; | ||||||
8071 | if( fLockAtn ) a8Bit |= 0x10; | ||||||
8072 | if( fMirrorMargins ) a8Bit |= 0x20; | ||||||
8073 | if( fReadOnlyRecommended ) a8Bit |= 0x40; | ||||||
8074 | if( fDfltTrueType ) a8Bit |= 0x80; | ||||||
8075 | Set_UInt8( pData, a8Bit ); | ||||||
8076 | |||||||
8077 | a8Bit = 0; // 7 0x07 | ||||||
8078 | if( fPagSuppressTopSpacing ) a8Bit |= 0x01; | ||||||
8079 | if( fProtEnabled ) a8Bit |= 0x02; | ||||||
8080 | if( fDispFormFieldSel ) a8Bit |= 0x04; | ||||||
8081 | if( fRMView ) a8Bit |= 0x08; | ||||||
8082 | if( fRMPrint ) a8Bit |= 0x10; | ||||||
8083 | if( fWriteReservation ) a8Bit |= 0x20; | ||||||
8084 | if( fLockRev ) a8Bit |= 0x40; | ||||||
8085 | if( fEmbedFonts ) a8Bit |= 0x80; | ||||||
8086 | Set_UInt8( pData, a8Bit ); | ||||||
8087 | |||||||
8088 | a8Bit = 0; // 8 0x08 | ||||||
8089 | if( copts_fNoTabForInd ) a8Bit |= 0x01; | ||||||
8090 | if( copts_fNoSpaceRaiseLower ) a8Bit |= 0x02; | ||||||
8091 | if( copts_fSupressSpbfAfterPgBrk ) a8Bit |= 0x04; | ||||||
8092 | if( copts_fWrapTrailSpaces ) a8Bit |= 0x08; | ||||||
8093 | if( copts_fMapPrintTextColor ) a8Bit |= 0x10; | ||||||
8094 | if( copts_fNoColumnBalance ) a8Bit |= 0x20; | ||||||
8095 | if( copts_fConvMailMergeEsc ) a8Bit |= 0x40; | ||||||
8096 | if( copts_fSupressTopSpacing ) a8Bit |= 0x80; | ||||||
8097 | Set_UInt8( pData, a8Bit ); | ||||||
8098 | |||||||
8099 | a8Bit = 0; // 9 0x09 | ||||||
8100 | if( copts_fOrigWordTableRules ) a8Bit |= 0x01; | ||||||
8101 | if( copts_fTransparentMetafiles ) a8Bit |= 0x02; | ||||||
8102 | if( copts_fShowBreaksInFrames ) a8Bit |= 0x04; | ||||||
8103 | if( copts_fSwapBordersFacingPgs ) a8Bit |= 0x08; | ||||||
8104 | if( copts_fExpShRtn ) a8Bit |= 0x20; // #i56856# | ||||||
8105 | Set_UInt8( pData, a8Bit ); | ||||||
8106 | |||||||
8107 | Set_UInt16( pData, dxaTab ); // 10 0x0a | ||||||
8108 | Set_UInt16( pData, wSpare ); // 12 0x0c | ||||||
8109 | Set_UInt16( pData, dxaHotZ ); // 14 0x0e | ||||||
8110 | Set_UInt16( pData, cConsecHypLim ); // 16 0x10 | ||||||
8111 | Set_UInt16( pData, wSpare2 ); // 18 0x12 | ||||||
8112 | Set_UInt32( pData, dttmCreated ); // 20 0x14 | ||||||
8113 | Set_UInt32( pData, dttmRevised ); // 24 0x18 | ||||||
8114 | Set_UInt32( pData, dttmLastPrint ); // 28 0x1c | ||||||
8115 | Set_UInt16( pData, nRevision ); // 32 0x20 | ||||||
8116 | Set_UInt32( pData, tmEdited ); // 34 0x22 | ||||||
8117 | Set_UInt32( pData, cWords ); // 38 0x26 | ||||||
8118 | Set_UInt32( pData, cCh ); // 42 0x2a | ||||||
8119 | Set_UInt16( pData, cPg ); // 46 0x2e | ||||||
8120 | Set_UInt32( pData, cParas ); // 48 0x30 | ||||||
8121 | |||||||
8122 | a16Bit = 0; // 52 0x34 | ||||||
8123 | a16Bit |= ( 0x0003 & rncEdn ); | ||||||
8124 | a16Bit |= (~0x0003 & ( nEdn << 2)); | ||||||
8125 | Set_UInt16( pData, a16Bit ); | ||||||
8126 | |||||||
8127 | a16Bit = 0; // 54 0x36 | ||||||
8128 | a16Bit |= (0x0003 & epc ); | ||||||
8129 | a16Bit |= (0x003c & (nfcFootnoteRef << 2)); | ||||||
8130 | a16Bit |= (0x03c0 & (nfcEdnRef << 6)); | ||||||
8131 | if( fPrintFormData ) a16Bit |= 0x0400; | ||||||
8132 | if( fSaveFormData ) a16Bit |= 0x0800; | ||||||
8133 | if( fShadeFormData ) a16Bit |= 0x1000; | ||||||
8134 | if( fWCFootnoteEdn ) a16Bit |= 0x8000; | ||||||
8135 | Set_UInt16( pData, a16Bit ); | ||||||
8136 | |||||||
8137 | Set_UInt32( pData, cLines ); // 56 0x38 | ||||||
8138 | Set_UInt32( pData, cWordsFootnoteEnd ); // 60 0x3c | ||||||
8139 | Set_UInt32( pData, cChFootnoteEdn ); // 64 0x40 | ||||||
8140 | Set_UInt16( pData, cPgFootnoteEdn ); // 68 0x44 | ||||||
8141 | Set_UInt32( pData, cParasFootnoteEdn ); // 70 0x46 | ||||||
8142 | Set_UInt32( pData, cLinesFootnoteEdn ); // 74 0x4a | ||||||
8143 | Set_UInt32( pData, lKeyProtDoc ); // 78 0x4e | ||||||
8144 | |||||||
8145 | a16Bit = 0; // 82 0x52 | ||||||
8146 | if (wvkSaved) | ||||||
8147 | a16Bit |= 0x0007; | ||||||
8148 | a16Bit |= (0x0ff8 & (wScaleSaved << 3)); | ||||||
8149 | a16Bit |= (0x3000 & (zkSaved << 12)); | ||||||
8150 | Set_UInt16( pData, a16Bit ); | ||||||
8151 | |||||||
8152 | if( 8 == rFib.m_nVersion ) | ||||||
8153 | { | ||||||
8154 | Set_UInt32(pData, GetCompatibilityOptions()); // 84 0x54 | ||||||
8155 | |||||||
8156 | Set_UInt16( pData, adt ); // 88 0x58 | ||||||
8157 | |||||||
8158 | doptypography.WriteToMem(pData); // 400 0x190 | ||||||
8159 | |||||||
8160 | memcpy( pData, &dogrid, sizeof( WW8_DOGRID )); | ||||||
8161 | pData += sizeof( WW8_DOGRID ); | ||||||
8162 | |||||||
8163 | a16Bit = 0x12; // set lvl to 9 // 410 0x19a | ||||||
8164 | if( fHtmlDoc ) a16Bit |= 0x0200; | ||||||
8165 | if( fSnapBorder ) a16Bit |= 0x0800; | ||||||
8166 | if( fIncludeHeader ) a16Bit |= 0x1000; | ||||||
8167 | if( fIncludeFooter ) a16Bit |= 0x2000; | ||||||
8168 | if( fForcePageSizePag ) a16Bit |= 0x4000; | ||||||
8169 | if( fMinFontSizePag ) a16Bit |= 0x8000; | ||||||
8170 | Set_UInt16( pData, a16Bit ); | ||||||
8171 | |||||||
8172 | a16Bit = 0; // 412 0x19c | ||||||
8173 | if( fHaveVersions ) a16Bit |= 0x0001; | ||||||
8174 | if( fAutoVersion ) a16Bit |= 0x0002; | ||||||
8175 | Set_UInt16( pData, a16Bit ); | ||||||
8176 | |||||||
8177 | pData += 12; // 414 0x19e | ||||||
8178 | |||||||
8179 | Set_UInt32( pData, cChWS ); // 426 0x1aa | ||||||
8180 | Set_UInt32( pData, cChWSFootnoteEdn ); // 430 0x1ae | ||||||
8181 | Set_UInt32( pData, grfDocEvents ); // 434 0x1b2 | ||||||
8182 | |||||||
8183 | pData += 4+30+8; // 438 0x1b6; 442 0x1ba; 472 0x1d8; 476 0x1dc | ||||||
8184 | |||||||
8185 | Set_UInt32( pData, cDBC ); // 480 0x1e0 | ||||||
8186 | Set_UInt32( pData, cDBCFootnoteEdn ); // 484 0x1e4 | ||||||
8187 | |||||||
8188 | pData += 1 * sizeof( sal_Int32); // 488 0x1e8 | ||||||
8189 | |||||||
8190 | Set_UInt16( pData, nfcFootnoteRef ); // 492 0x1ec | ||||||
8191 | Set_UInt16( pData, nfcEdnRef ); // 494 0x1ee | ||||||
8192 | Set_UInt16( pData, hpsZoomFontPag ); // 496 0x1f0 | ||||||
8193 | Set_UInt16( pData, dywDispPag ); // 498 0x1f2 | ||||||
8194 | |||||||
8195 | //500 -> 508, Appear to be repeated here in 2000+ | ||||||
8196 | pData += 8; | ||||||
8197 | Set_UInt32(pData, GetCompatibilityOptions()); | ||||||
8198 | Set_UInt32(pData, GetCompatibilityOptions2()); | ||||||
8199 | pData += 32; | ||||||
8200 | |||||||
8201 | a16Bit = 0; | ||||||
8202 | if (fEmbedFactoids) | ||||||
8203 | a16Bit |= 0x8; | ||||||
8204 | if (fAcetateShowMarkup) | ||||||
8205 | a16Bit |= 0x1000; | ||||||
8206 | //Word XP at least requires fAcetateShowMarkup to honour fAcetateShowAtn | ||||||
8207 | if (fAcetateShowAtn) | ||||||
8208 | { | ||||||
8209 | a16Bit |= 0x1000; | ||||||
8210 | a16Bit |= 0x2000; | ||||||
8211 | } | ||||||
8212 | Set_UInt16(pData, a16Bit); | ||||||
8213 | |||||||
8214 | pData += 48; | ||||||
8215 | a16Bit = 0x0080; | ||||||
8216 | Set_UInt16(pData, a16Bit); | ||||||
8217 | } | ||||||
8218 | rStrm.WriteBytes(aData, nLen); | ||||||
8219 | } | ||||||
8220 | |||||||
8221 | void WW8DopTypography::ReadFromMem(sal_uInt8 *&pData) | ||||||
8222 | { | ||||||
8223 | sal_uInt16 a16Bit = Get_UShort(pData); | ||||||
8224 | m_fKerningPunct = (a16Bit & 0x0001); | ||||||
8225 | m_iJustification = (a16Bit & 0x0006) >> 1; | ||||||
8226 | m_iLevelOfKinsoku = (a16Bit & 0x0018) >> 3; | ||||||
8227 | m_f2on1 = (a16Bit & 0x0020) >> 5; | ||||||
8228 | m_reserved1 = (a16Bit & 0x03C0) >> 6; | ||||||
8229 | m_reserved2 = (a16Bit & 0xFC00) >> 10; | ||||||
8230 | |||||||
8231 | m_cchFollowingPunct = Get_Short(pData); | ||||||
8232 | m_cchLeadingPunct = Get_Short(pData); | ||||||
8233 | |||||||
8234 | sal_Int16 i; | ||||||
8235 | for (i=0; i < nMaxFollowing; ++i) | ||||||
8236 | m_rgxchFPunct[i] = Get_Short(pData); | ||||||
8237 | for (i=0; i < nMaxLeading; ++i) | ||||||
8238 | m_rgxchLPunct[i] = Get_Short(pData); | ||||||
8239 | |||||||
8240 | if (m_cchFollowingPunct >= 0 && m_cchFollowingPunct < nMaxFollowing) | ||||||
8241 | m_rgxchFPunct[m_cchFollowingPunct]=0; | ||||||
8242 | else | ||||||
8243 | m_rgxchFPunct[nMaxFollowing - 1]=0; | ||||||
8244 | |||||||
8245 | if (m_cchLeadingPunct >= 0 && m_cchLeadingPunct < nMaxLeading) | ||||||
8246 | m_rgxchLPunct[m_cchLeadingPunct]=0; | ||||||
8247 | else | ||||||
8248 | m_rgxchLPunct[nMaxLeading - 1]=0; | ||||||
8249 | |||||||
8250 | } | ||||||
8251 | |||||||
8252 | void WW8DopTypography::WriteToMem(sal_uInt8 *&pData) const | ||||||
8253 | { | ||||||
8254 | sal_uInt16 a16Bit = sal_uInt16(m_fKerningPunct); | ||||||
8255 | a16Bit |= (m_iJustification << 1) & 0x0006; | ||||||
8256 | a16Bit |= (m_iLevelOfKinsoku << 3) & 0x0018; | ||||||
8257 | a16Bit |= (int(m_f2on1) << 5) & 0x0020; | ||||||
8258 | a16Bit |= (m_reserved1 << 6) & 0x03C0; | ||||||
8259 | a16Bit |= (m_reserved2 << 10) & 0xFC00; | ||||||
8260 | Set_UInt16(pData,a16Bit); | ||||||
8261 | |||||||
8262 | Set_UInt16(pData,m_cchFollowingPunct); | ||||||
8263 | Set_UInt16(pData,m_cchLeadingPunct); | ||||||
8264 | |||||||
8265 | sal_Int16 i; | ||||||
8266 | for (i=0; i < nMaxFollowing; ++i) | ||||||
8267 | Set_UInt16(pData,m_rgxchFPunct[i]); | ||||||
8268 | for (i=0; i < nMaxLeading; ++i) | ||||||
8269 | Set_UInt16(pData,m_rgxchLPunct[i]); | ||||||
8270 | } | ||||||
8271 | |||||||
8272 | LanguageType WW8DopTypography::GetConvertedLang() const | ||||||
8273 | { | ||||||
8274 | LanguageType nLang; | ||||||
8275 | //I have assumed people's republic/taiwan == simplified/traditional | ||||||
8276 | |||||||
8277 | //This isn't a documented issue, so we might have it all wrong, | ||||||
8278 | //i.e. i.e. what's with the powers of two ? | ||||||
8279 | |||||||
8280 | /* | ||||||
8281 | One example of 3 for reserved1 which was really Japanese, perhaps last bit | ||||||
8282 | is for some other use ?, or redundant. If more examples trigger the assert | ||||||
8283 | we might be able to figure it out. | ||||||
8284 | */ | ||||||
8285 | switch(m_reserved1 & 0xE) | ||||||
8286 | { | ||||||
8287 | case 2: //Japan | ||||||
8288 | nLang = LANGUAGE_JAPANESELanguageType(0x0411); | ||||||
8289 | break; | ||||||
8290 | case 4: //Chinese (People's Republic) | ||||||
8291 | nLang = LANGUAGE_CHINESE_SIMPLIFIEDLanguageType(0x0804); | ||||||
8292 | break; | ||||||
8293 | case 6: //Korean | ||||||
8294 | nLang = LANGUAGE_KOREANLanguageType(0x0412); | ||||||
8295 | break; | ||||||
8296 | case 8: //Chinese (Taiwan) | ||||||
8297 | nLang = LANGUAGE_CHINESE_TRADITIONALLanguageType(0x0404); | ||||||
8298 | break; | ||||||
8299 | default: | ||||||
8300 | OSL_ENSURE(false, "Unknown MS Asian Typography language, report")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8300" ": "), "%s", "Unknown MS Asian Typography language, report" ); } } while (false); | ||||||
8301 | nLang = LANGUAGE_CHINESE_SIMPLIFIED_LEGACYLanguageType(0x0004); | ||||||
8302 | break; | ||||||
8303 | case 0: | ||||||
8304 | //And here we have the possibility that it says 2, but it's really | ||||||
8305 | //a bug and only japanese level 2 has been selected after a custom | ||||||
8306 | //version was chosen on last save! | ||||||
8307 | nLang = LANGUAGE_JAPANESELanguageType(0x0411); | ||||||
8308 | break; | ||||||
8309 | } | ||||||
8310 | return nLang; | ||||||
8311 | } | ||||||
8312 | |||||||
8313 | // Sprms | ||||||
8314 | |||||||
8315 | sal_uInt16 wwSprmParser::GetSprmTailLen(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen) | ||||||
8316 | const | ||||||
8317 | { | ||||||
8318 | SprmInfo aSprm = GetSprmInfo(nId); | ||||||
8319 | sal_uInt16 nL = 0; // number of Bytes to read | ||||||
8320 | |||||||
8321 | //sprmPChgTabs | ||||||
8322 | switch( nId ) | ||||||
8323 | { | ||||||
8324 | case 23: | ||||||
8325 | case 0xC615: | ||||||
8326 | if( pSprm[1 + mnDelta] != 255 ) | ||||||
8327 | nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen); | ||||||
8328 | else | ||||||
8329 | { | ||||||
8330 | sal_uInt8 nDelIdx = 2 + mnDelta; | ||||||
8331 | sal_uInt8 nDel = nDelIdx < nRemLen ? pSprm[nDelIdx] : 0; | ||||||
8332 | sal_uInt8 nInsIdx = 3 + mnDelta + 4 * nDel; | ||||||
8333 | sal_uInt8 nIns = nInsIdx < nRemLen ? pSprm[nInsIdx] : 0; | ||||||
8334 | |||||||
8335 | nL = 2 + 4 * nDel + 3 * nIns; | ||||||
8336 | } | ||||||
8337 | break; | ||||||
8338 | case 0xD608: | ||||||
8339 | { | ||||||
8340 | sal_uInt8 nIndex = 1 + mnDelta; | ||||||
8341 | if (nIndex + 1 >= nRemLen) | ||||||
8342 | { | ||||||
8343 | SAL_WARN("sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8343" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8343" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8343" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8343" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
8344 | nL = 0; | ||||||
8345 | } | ||||||
8346 | else | ||||||
8347 | nL = SVBT16ToUInt16(&pSprm[nIndex]); | ||||||
8348 | break; | ||||||
8349 | } | ||||||
8350 | default: | ||||||
8351 | switch (aSprm.nVari) | ||||||
8352 | { | ||||||
8353 | case L_FIX: | ||||||
8354 | nL = aSprm.nLen; // Excl. Token | ||||||
8355 | break; | ||||||
8356 | case L_VAR: | ||||||
8357 | // Variable 1-Byte Length? | ||||||
8358 | // Excl. Token + Var-Lengthbyte | ||||||
8359 | nL = static_cast< sal_uInt16 >(pSprm[1 + mnDelta] + aSprm.nLen); | ||||||
8360 | break; | ||||||
8361 | case L_VAR2: | ||||||
8362 | { | ||||||
8363 | // Variable 2-Byte Length? | ||||||
8364 | // Excl. Token + Var-Lengthbyte | ||||||
8365 | sal_uInt8 nIndex = 1 + mnDelta; | ||||||
8366 | sal_uInt16 nCount; | ||||||
8367 | if (nIndex + 1 >= nRemLen) | ||||||
8368 | { | ||||||
8369 | SAL_WARN("sw.ww8", "sprm longer than remaining bytes, doc or parser is wrong")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8369" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8369" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm longer than remaining bytes, doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8369" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm longer than remaining bytes, doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm longer than remaining bytes, doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8369" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
8370 | nCount = 0; | ||||||
8371 | } | ||||||
8372 | else | ||||||
8373 | nCount = SVBT16ToUInt16(&pSprm[nIndex]); | ||||||
8374 | nL = static_cast< sal_uInt16 >(nCount + aSprm.nLen - 1); | ||||||
8375 | break; | ||||||
8376 | } | ||||||
8377 | default: | ||||||
8378 | OSL_ENSURE(false, "Unknown sprm variant")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8378" ": "), "%s", "Unknown sprm variant"); } } while ( false); | ||||||
8379 | break; | ||||||
8380 | } | ||||||
8381 | break; | ||||||
8382 | } | ||||||
8383 | return nL; | ||||||
8384 | } | ||||||
8385 | |||||||
8386 | // one or two bytes at the beginning at the sprm id | ||||||
8387 | sal_uInt16 wwSprmParser::GetSprmId(const sal_uInt8* pSp) const | ||||||
8388 | { | ||||||
8389 | OSL_ENSURE(pSp, "Why GetSprmId with pSp of 0")do { if (true && (!(pSp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8389" ": "), "%s", "Why GetSprmId with pSp of 0"); } } while (false); | ||||||
8390 | if (!pSp) | ||||||
8391 | return 0; | ||||||
8392 | |||||||
8393 | sal_uInt16 nId = 0; | ||||||
8394 | |||||||
8395 | if (ww::IsSevenMinus(meVersion)) | ||||||
8396 | { | ||||||
8397 | nId = *pSp; // [0..0xff] | ||||||
8398 | } | ||||||
8399 | else | ||||||
8400 | { | ||||||
8401 | nId = SVBT16ToUInt16(pSp); | ||||||
8402 | if (0x0800 > nId) | ||||||
8403 | nId = 0; | ||||||
8404 | } | ||||||
8405 | |||||||
8406 | return nId; | ||||||
8407 | } | ||||||
8408 | |||||||
8409 | // with tokens and length byte | ||||||
8410 | sal_Int32 wwSprmParser::GetSprmSize(sal_uInt16 nId, const sal_uInt8* pSprm, sal_Int32 nRemLen) const | ||||||
8411 | { | ||||||
8412 | return GetSprmTailLen(nId, pSprm, nRemLen) + 1 + mnDelta + SprmDataOfs(nId); | ||||||
8413 | } | ||||||
8414 | |||||||
8415 | sal_uInt8 wwSprmParser::SprmDataOfs(sal_uInt16 nId) const | ||||||
8416 | { | ||||||
8417 | return GetSprmInfo(nId).nVari; | ||||||
8418 | } | ||||||
8419 | |||||||
8420 | sal_Int32 wwSprmParser::DistanceToData(sal_uInt16 nId) const | ||||||
8421 | { | ||||||
8422 | return 1 + mnDelta + SprmDataOfs(nId); | ||||||
8423 | } | ||||||
8424 | |||||||
8425 | SprmResult wwSprmParser::findSprmData(sal_uInt16 nId, sal_uInt8* pSprms, | ||||||
8426 | sal_Int32 nLen) const | ||||||
8427 | { | ||||||
8428 | while (nLen >= MinSprmLen()) | ||||||
8429 | { | ||||||
8430 | const sal_uInt16 nCurrentId = GetSprmId(pSprms); | ||||||
8431 | // set pointer to data | ||||||
8432 | sal_Int32 nSize = GetSprmSize(nCurrentId, pSprms, nLen); | ||||||
8433 | |||||||
8434 | bool bValid = nSize <= nLen; | ||||||
8435 | |||||||
8436 | SAL_WARN_IF(!bValid, "sw.ww8",do { if (true && (!bValid)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
8437 | "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " <<do { if (true && (!bValid)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | ||||||
8438 | nSize << " vs " << nLen << "doc or parser is wrong")do { if (true && (!bValid)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "sw.ww8")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sprm 0x" << std::hex << nCurrentId << std::dec << " longer than remaining bytes, " << nSize << " vs " << nLen << "doc or parser is wrong" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sw.ww8" ), ("/home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx" ":" "8438" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
8439 | |||||||
8440 | if (nCurrentId == nId && bValid) // Sprm found | ||||||
8441 | { | ||||||
8442 | sal_Int32 nFixedLen = DistanceToData(nId); | ||||||
8443 | return SprmResult(pSprms + nFixedLen, nSize - nFixedLen); | ||||||
8444 | } | ||||||
8445 | |||||||
8446 | //Clip to available size if wrong | ||||||
8447 | nSize = std::min(nSize, nLen); | ||||||
8448 | pSprms += nSize; | ||||||
8449 | nLen -= nSize; | ||||||
8450 | } | ||||||
8451 | // Sprm not found | ||||||
8452 | return SprmResult(); | ||||||
8453 | } | ||||||
8454 | |||||||
8455 | SEPr::SEPr() : | ||||||
8456 | bkc(2), fTitlePage(0), fAutoPgn(0), nfcPgn(0), fUnlocked(0), cnsPgn(0), | ||||||
8457 | fPgnRestart(0), fEndNote(1), lnc(0), grpfIhdt(0), nLnnMod(0), dxaLnn(0), | ||||||
8458 | dxaPgn(720), dyaPgn(720), fLBetween(0), vjc(0), dmBinFirst(0), | ||||||
8459 | dmBinOther(0), dmPaperReq(0), fPropRMark(0), ibstPropRMark(0), | ||||||
8460 | dttmPropRMark(0), dxtCharSpace(0), dyaLinePitch(0), clm(0), reserved1(0), | ||||||
8461 | dmOrientPage(0), iHeadingPgn(0), pgnStart(1), lnnMin(0), wTextFlow(0), | ||||||
8462 | reserved2(0), pgbApplyTo(0), pgbPageDepth(0), pgbOffsetFrom(0), | ||||||
8463 | xaPage(lLetterWidth), yaPage(lLetterHeight), xaPageNUp(lLetterWidth), yaPageNUp(lLetterHeight), | ||||||
8464 | dxaLeft(1800), dxaRight(1800), dyaTop(1440), dyaBottom(1440), dzaGutter(0), | ||||||
8465 | dyaHdrTop(720), dyaHdrBottom(720), ccolM1(0), fEvenlySpaced(1), | ||||||
8466 | reserved3(0), fBiDi(0), fFacingCol(0), fRTLGutter(0), fRTLAlignment(0), | ||||||
8467 | dxaColumns(720), dxaColumnWidth(0), dmOrientFirst(0), fLayout(0), | ||||||
8468 | reserved4(0) | ||||||
8469 | { | ||||||
8470 | } | ||||||
8471 | |||||||
8472 | bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength) | ||||||
8473 | { | ||||||
8474 | return (rSt.ReadBytes(pDest, nLength) == static_cast<std::size_t>(nLength)); | ||||||
8475 | } | ||||||
8476 | |||||||
8477 | #ifdef OSL_BIGENDIAN | ||||||
8478 | void swapEndian(sal_Unicode *pString) | ||||||
8479 | { | ||||||
8480 | for (sal_Unicode *pWork = pString; *pWork; ++pWork) | ||||||
8481 | *pWork = OSL_SWAPWORD(*pWork)((sal_uInt16)((sal_uInt16)((((sal_uInt8)(((sal_uInt16)(*pWork ) >> 8) & 0xFF))) & 0xFF) | (((sal_uInt16)(((sal_uInt8 )((sal_uInt16)(*pWork) & 0xFF))) & 0xFF) << 8)) ); | ||||||
8482 | } | ||||||
8483 | #endif | ||||||
8484 | |||||||
8485 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |