File: | home/maarten/src/libreoffice/core/sw/source/filter/ww8/ww8scan.cxx |
Warning: | line 4055, column 44 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 || (static_cast<sal_uInt8*>(pData)[0] & 0x1f) != 0x13) // No beginning? | |||
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 ? static_cast<void*>(&pPLCF_Contents[nInIdx * nStru]) : nullptr; | |||
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: */ |
1 | // unique_ptr implementation -*- C++ -*- |
2 | |
3 | // Copyright (C) 2008-2020 Free Software Foundation, Inc. |
4 | // |
5 | // This file is part of the GNU ISO C++ Library. This library is free |
6 | // software; you can redistribute it and/or modify it under the |
7 | // terms of the GNU General Public License as published by the |
8 | // Free Software Foundation; either version 3, or (at your option) |
9 | // any later version. |
10 | |
11 | // This library is distributed in the hope that it will be useful, |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | // GNU General Public License for more details. |
15 | |
16 | // Under Section 7 of GPL version 3, you are granted additional |
17 | // permissions described in the GCC Runtime Library Exception, version |
18 | // 3.1, as published by the Free Software Foundation. |
19 | |
20 | // You should have received a copy of the GNU General Public License and |
21 | // a copy of the GCC Runtime Library Exception along with this program; |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |
23 | // <http://www.gnu.org/licenses/>. |
24 | |
25 | /** @file bits/unique_ptr.h |
26 | * This is an internal header file, included by other library headers. |
27 | * Do not attempt to use it directly. @headername{memory} |
28 | */ |
29 | |
30 | #ifndef _UNIQUE_PTR_H1 |
31 | #define _UNIQUE_PTR_H1 1 |
32 | |
33 | #include <bits/c++config.h> |
34 | #include <debug/assertions.h> |
35 | #include <type_traits> |
36 | #include <utility> |
37 | #include <tuple> |
38 | #include <bits/stl_function.h> |
39 | #include <bits/functional_hash.h> |
40 | #if __cplusplus201703L > 201703L |
41 | # include <compare> |
42 | # include <ostream> |
43 | #endif |
44 | |
45 | namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default"))) |
46 | { |
47 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
48 | |
49 | /** |
50 | * @addtogroup pointer_abstractions |
51 | * @{ |
52 | */ |
53 | |
54 | #if _GLIBCXX_USE_DEPRECATED1 |
55 | #pragma GCC diagnostic push |
56 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
57 | template<typename> class auto_ptr; |
58 | #pragma GCC diagnostic pop |
59 | #endif |
60 | |
61 | /// Primary template of default_delete, used by unique_ptr for single objects |
62 | template<typename _Tp> |
63 | struct default_delete |
64 | { |
65 | /// Default constructor |
66 | constexpr default_delete() noexcept = default; |
67 | |
68 | /** @brief Converting constructor. |
69 | * |
70 | * Allows conversion from a deleter for objects of another type, `_Up`, |
71 | * only if `_Up*` is convertible to `_Tp*`. |
72 | */ |
73 | template<typename _Up, |
74 | typename = _Require<is_convertible<_Up*, _Tp*>>> |
75 | default_delete(const default_delete<_Up>&) noexcept { } |
76 | |
77 | /// Calls `delete __ptr` |
78 | void |
79 | operator()(_Tp* __ptr) const |
80 | { |
81 | static_assert(!is_void<_Tp>::value, |
82 | "can't delete pointer to incomplete type"); |
83 | static_assert(sizeof(_Tp)>0, |
84 | "can't delete pointer to incomplete type"); |
85 | delete __ptr; |
86 | } |
87 | }; |
88 | |
89 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
90 | // DR 740 - omit specialization for array objects with a compile time length |
91 | |
92 | /// Specialization of default_delete for arrays, used by `unique_ptr<T[]>` |
93 | template<typename _Tp> |
94 | struct default_delete<_Tp[]> |
95 | { |
96 | public: |
97 | /// Default constructor |
98 | constexpr default_delete() noexcept = default; |
99 | |
100 | /** @brief Converting constructor. |
101 | * |
102 | * Allows conversion from a deleter for arrays of another type, such as |
103 | * a const-qualified version of `_Tp`. |
104 | * |
105 | * Conversions from types derived from `_Tp` are not allowed because |
106 | * it is undefined to `delete[]` an array of derived types through a |
107 | * pointer to the base type. |
108 | */ |
109 | template<typename _Up, |
110 | typename = _Require<is_convertible<_Up(*)[], _Tp(*)[]>>> |
111 | default_delete(const default_delete<_Up[]>&) noexcept { } |
112 | |
113 | /// Calls `delete[] __ptr` |
114 | template<typename _Up> |
115 | typename enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value>::type |
116 | operator()(_Up* __ptr) const |
117 | { |
118 | static_assert(sizeof(_Tp)>0, |
119 | "can't delete pointer to incomplete type"); |
120 | delete [] __ptr; |
121 | } |
122 | }; |
123 | |
124 | /// @cond undocumented |
125 | |
126 | // Manages the pointer and deleter of a unique_ptr |
127 | template <typename _Tp, typename _Dp> |
128 | class __uniq_ptr_impl |
129 | { |
130 | template <typename _Up, typename _Ep, typename = void> |
131 | struct _Ptr |
132 | { |
133 | using type = _Up*; |
134 | }; |
135 | |
136 | template <typename _Up, typename _Ep> |
137 | struct |
138 | _Ptr<_Up, _Ep, __void_t<typename remove_reference<_Ep>::type::pointer>> |
139 | { |
140 | using type = typename remove_reference<_Ep>::type::pointer; |
141 | }; |
142 | |
143 | public: |
144 | using _DeleterConstraint = enable_if< |
145 | __and_<__not_<is_pointer<_Dp>>, |
146 | is_default_constructible<_Dp>>::value>; |
147 | |
148 | using pointer = typename _Ptr<_Tp, _Dp>::type; |
149 | |
150 | static_assert( !is_rvalue_reference<_Dp>::value, |
151 | "unique_ptr's deleter type must be a function object type" |
152 | " or an lvalue reference type" ); |
153 | |
154 | __uniq_ptr_impl() = default; |
155 | __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; } |
156 | |
157 | template<typename _Del> |
158 | __uniq_ptr_impl(pointer __p, _Del&& __d) |
159 | : _M_t(__p, std::forward<_Del>(__d)) { } |
160 | |
161 | __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept |
162 | : _M_t(std::move(__u._M_t)) |
163 | { __u._M_ptr() = nullptr; } |
164 | |
165 | __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept |
166 | { |
167 | reset(__u.release()); |
168 | _M_deleter() = std::forward<_Dp>(__u._M_deleter()); |
169 | return *this; |
170 | } |
171 | |
172 | pointer& _M_ptr() { return std::get<0>(_M_t); } |
173 | pointer _M_ptr() const { return std::get<0>(_M_t); } |
174 | _Dp& _M_deleter() { return std::get<1>(_M_t); } |
175 | const _Dp& _M_deleter() const { return std::get<1>(_M_t); } |
176 | |
177 | void reset(pointer __p) noexcept |
178 | { |
179 | const pointer __old_p = _M_ptr(); |
180 | _M_ptr() = __p; |
181 | if (__old_p) |
182 | _M_deleter()(__old_p); |
183 | } |
184 | |
185 | pointer release() noexcept |
186 | { |
187 | pointer __p = _M_ptr(); |
188 | _M_ptr() = nullptr; |
189 | return __p; |
190 | } |
191 | |
192 | void |
193 | swap(__uniq_ptr_impl& __rhs) noexcept |
194 | { |
195 | using std::swap; |
196 | swap(this->_M_ptr(), __rhs._M_ptr()); |
197 | swap(this->_M_deleter(), __rhs._M_deleter()); |
198 | } |
199 | |
200 | private: |
201 | tuple<pointer, _Dp> _M_t; |
202 | }; |
203 | |
204 | // Defines move construction + assignment as either defaulted or deleted. |
205 | template <typename _Tp, typename _Dp, |
206 | bool = is_move_constructible<_Dp>::value, |
207 | bool = is_move_assignable<_Dp>::value> |
208 | struct __uniq_ptr_data : __uniq_ptr_impl<_Tp, _Dp> |
209 | { |
210 | using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; |
211 | __uniq_ptr_data(__uniq_ptr_data&&) = default; |
212 | __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default; |
213 | }; |
214 | |
215 | template <typename _Tp, typename _Dp> |
216 | struct __uniq_ptr_data<_Tp, _Dp, true, false> : __uniq_ptr_impl<_Tp, _Dp> |
217 | { |
218 | using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; |
219 | __uniq_ptr_data(__uniq_ptr_data&&) = default; |
220 | __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete; |
221 | }; |
222 | |
223 | template <typename _Tp, typename _Dp> |
224 | struct __uniq_ptr_data<_Tp, _Dp, false, true> : __uniq_ptr_impl<_Tp, _Dp> |
225 | { |
226 | using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; |
227 | __uniq_ptr_data(__uniq_ptr_data&&) = delete; |
228 | __uniq_ptr_data& operator=(__uniq_ptr_data&&) = default; |
229 | }; |
230 | |
231 | template <typename _Tp, typename _Dp> |
232 | struct __uniq_ptr_data<_Tp, _Dp, false, false> : __uniq_ptr_impl<_Tp, _Dp> |
233 | { |
234 | using __uniq_ptr_impl<_Tp, _Dp>::__uniq_ptr_impl; |
235 | __uniq_ptr_data(__uniq_ptr_data&&) = delete; |
236 | __uniq_ptr_data& operator=(__uniq_ptr_data&&) = delete; |
237 | }; |
238 | /// @endcond |
239 | |
240 | /// 20.7.1.2 unique_ptr for single objects. |
241 | template <typename _Tp, typename _Dp = default_delete<_Tp>> |
242 | class unique_ptr |
243 | { |
244 | template <typename _Up> |
245 | using _DeleterConstraint = |
246 | typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; |
247 | |
248 | __uniq_ptr_data<_Tp, _Dp> _M_t; |
249 | |
250 | public: |
251 | using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; |
252 | using element_type = _Tp; |
253 | using deleter_type = _Dp; |
254 | |
255 | private: |
256 | // helper template for detecting a safe conversion from another |
257 | // unique_ptr |
258 | template<typename _Up, typename _Ep> |
259 | using __safe_conversion_up = __and_< |
260 | is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>, |
261 | __not_<is_array<_Up>> |
262 | >; |
263 | |
264 | public: |
265 | // Constructors. |
266 | |
267 | /// Default constructor, creates a unique_ptr that owns nothing. |
268 | template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> |
269 | constexpr unique_ptr() noexcept |
270 | : _M_t() |
271 | { } |
272 | |
273 | /** Takes ownership of a pointer. |
274 | * |
275 | * @param __p A pointer to an object of @c element_type |
276 | * |
277 | * The deleter will be value-initialized. |
278 | */ |
279 | template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> |
280 | explicit |
281 | unique_ptr(pointer __p) noexcept |
282 | : _M_t(__p) |
283 | { } |
284 | |
285 | /** Takes ownership of a pointer. |
286 | * |
287 | * @param __p A pointer to an object of @c element_type |
288 | * @param __d A reference to a deleter. |
289 | * |
290 | * The deleter will be initialized with @p __d |
291 | */ |
292 | template<typename _Del = deleter_type, |
293 | typename = _Require<is_copy_constructible<_Del>>> |
294 | unique_ptr(pointer __p, const deleter_type& __d) noexcept |
295 | : _M_t(__p, __d) { } |
296 | |
297 | /** Takes ownership of a pointer. |
298 | * |
299 | * @param __p A pointer to an object of @c element_type |
300 | * @param __d An rvalue reference to a (non-reference) deleter. |
301 | * |
302 | * The deleter will be initialized with @p std::move(__d) |
303 | */ |
304 | template<typename _Del = deleter_type, |
305 | typename = _Require<is_move_constructible<_Del>>> |
306 | unique_ptr(pointer __p, |
307 | __enable_if_t<!is_lvalue_reference<_Del>::value, |
308 | _Del&&> __d) noexcept |
309 | : _M_t(__p, std::move(__d)) |
310 | { } |
311 | |
312 | template<typename _Del = deleter_type, |
313 | typename _DelUnref = typename remove_reference<_Del>::type> |
314 | unique_ptr(pointer, |
315 | __enable_if_t<is_lvalue_reference<_Del>::value, |
316 | _DelUnref&&>) = delete; |
317 | |
318 | /// Creates a unique_ptr that owns nothing. |
319 | template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> |
320 | constexpr unique_ptr(nullptr_t) noexcept |
321 | : _M_t() |
322 | { } |
323 | |
324 | // Move constructors. |
325 | |
326 | /// Move constructor. |
327 | unique_ptr(unique_ptr&&) = default; |
328 | |
329 | /** @brief Converting constructor from another type |
330 | * |
331 | * Requires that the pointer owned by @p __u is convertible to the |
332 | * type of pointer owned by this object, @p __u does not own an array, |
333 | * and @p __u has a compatible deleter type. |
334 | */ |
335 | template<typename _Up, typename _Ep, typename = _Require< |
336 | __safe_conversion_up<_Up, _Ep>, |
337 | typename conditional<is_reference<_Dp>::value, |
338 | is_same<_Ep, _Dp>, |
339 | is_convertible<_Ep, _Dp>>::type>> |
340 | unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept |
341 | : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) |
342 | { } |
343 | |
344 | #if _GLIBCXX_USE_DEPRECATED1 |
345 | #pragma GCC diagnostic push |
346 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
347 | /// Converting constructor from @c auto_ptr |
348 | template<typename _Up, typename = _Require< |
349 | is_convertible<_Up*, _Tp*>, is_same<_Dp, default_delete<_Tp>>>> |
350 | unique_ptr(auto_ptr<_Up>&& __u) noexcept; |
351 | #pragma GCC diagnostic pop |
352 | #endif |
353 | |
354 | /// Destructor, invokes the deleter if the stored pointer is not null. |
355 | ~unique_ptr() noexcept |
356 | { |
357 | static_assert(__is_invocable<deleter_type&, pointer>::value, |
358 | "unique_ptr's deleter must be invocable with a pointer"); |
359 | auto& __ptr = _M_t._M_ptr(); |
360 | if (__ptr != nullptr) |
361 | get_deleter()(std::move(__ptr)); |
362 | __ptr = pointer(); |
363 | } |
364 | |
365 | // Assignment. |
366 | |
367 | /** @brief Move assignment operator. |
368 | * |
369 | * Invokes the deleter if this object owns a pointer. |
370 | */ |
371 | unique_ptr& operator=(unique_ptr&&) = default; |
372 | |
373 | /** @brief Assignment from another type. |
374 | * |
375 | * @param __u The object to transfer ownership from, which owns a |
376 | * convertible pointer to a non-array object. |
377 | * |
378 | * Invokes the deleter if this object owns a pointer. |
379 | */ |
380 | template<typename _Up, typename _Ep> |
381 | typename enable_if< __and_< |
382 | __safe_conversion_up<_Up, _Ep>, |
383 | is_assignable<deleter_type&, _Ep&&> |
384 | >::value, |
385 | unique_ptr&>::type |
386 | operator=(unique_ptr<_Up, _Ep>&& __u) noexcept |
387 | { |
388 | reset(__u.release()); |
389 | get_deleter() = std::forward<_Ep>(__u.get_deleter()); |
390 | return *this; |
391 | } |
392 | |
393 | /// Reset the %unique_ptr to empty, invoking the deleter if necessary. |
394 | unique_ptr& |
395 | operator=(nullptr_t) noexcept |
396 | { |
397 | reset(); |
398 | return *this; |
399 | } |
400 | |
401 | // Observers. |
402 | |
403 | /// Dereference the stored pointer. |
404 | typename add_lvalue_reference<element_type>::type |
405 | operator*() const |
406 | { |
407 | __glibcxx_assert(get() != pointer()); |
408 | return *get(); |
409 | } |
410 | |
411 | /// Return the stored pointer. |
412 | pointer |
413 | operator->() const noexcept |
414 | { |
415 | _GLIBCXX_DEBUG_PEDASSERT(get() != pointer()); |
416 | return get(); |
417 | } |
418 | |
419 | /// Return the stored pointer. |
420 | pointer |
421 | get() const noexcept |
422 | { return _M_t._M_ptr(); } |
423 | |
424 | /// Return a reference to the stored deleter. |
425 | deleter_type& |
426 | get_deleter() noexcept |
427 | { return _M_t._M_deleter(); } |
428 | |
429 | /// Return a reference to the stored deleter. |
430 | const deleter_type& |
431 | get_deleter() const noexcept |
432 | { return _M_t._M_deleter(); } |
433 | |
434 | /// Return @c true if the stored pointer is not null. |
435 | explicit operator bool() const noexcept |
436 | { return get() == pointer() ? false : true; } |
437 | |
438 | // Modifiers. |
439 | |
440 | /// Release ownership of any stored pointer. |
441 | pointer |
442 | release() noexcept |
443 | { return _M_t.release(); } |
444 | |
445 | /** @brief Replace the stored pointer. |
446 | * |
447 | * @param __p The new pointer to store. |
448 | * |
449 | * The deleter will be invoked if a pointer is already owned. |
450 | */ |
451 | void |
452 | reset(pointer __p = pointer()) noexcept |
453 | { |
454 | static_assert(__is_invocable<deleter_type&, pointer>::value, |
455 | "unique_ptr's deleter must be invocable with a pointer"); |
456 | _M_t.reset(std::move(__p)); |
457 | } |
458 | |
459 | /// Exchange the pointer and deleter with another object. |
460 | void |
461 | swap(unique_ptr& __u) noexcept |
462 | { |
463 | static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); |
464 | _M_t.swap(__u._M_t); |
465 | } |
466 | |
467 | // Disable copy from lvalue. |
468 | unique_ptr(const unique_ptr&) = delete; |
469 | unique_ptr& operator=(const unique_ptr&) = delete; |
470 | }; |
471 | |
472 | /// 20.7.1.3 unique_ptr for array objects with a runtime length |
473 | // [unique.ptr.runtime] |
474 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
475 | // DR 740 - omit specialization for array objects with a compile time length |
476 | template<typename _Tp, typename _Dp> |
477 | class unique_ptr<_Tp[], _Dp> |
478 | { |
479 | template <typename _Up> |
480 | using _DeleterConstraint = |
481 | typename __uniq_ptr_impl<_Tp, _Up>::_DeleterConstraint::type; |
482 | |
483 | __uniq_ptr_data<_Tp, _Dp> _M_t; |
484 | |
485 | template<typename _Up> |
486 | using __remove_cv = typename remove_cv<_Up>::type; |
487 | |
488 | // like is_base_of<_Tp, _Up> but false if unqualified types are the same |
489 | template<typename _Up> |
490 | using __is_derived_Tp |
491 | = __and_< is_base_of<_Tp, _Up>, |
492 | __not_<is_same<__remove_cv<_Tp>, __remove_cv<_Up>>> >; |
493 | |
494 | public: |
495 | using pointer = typename __uniq_ptr_impl<_Tp, _Dp>::pointer; |
496 | using element_type = _Tp; |
497 | using deleter_type = _Dp; |
498 | |
499 | // helper template for detecting a safe conversion from another |
500 | // unique_ptr |
501 | template<typename _Up, typename _Ep, |
502 | typename _UPtr = unique_ptr<_Up, _Ep>, |
503 | typename _UP_pointer = typename _UPtr::pointer, |
504 | typename _UP_element_type = typename _UPtr::element_type> |
505 | using __safe_conversion_up = __and_< |
506 | is_array<_Up>, |
507 | is_same<pointer, element_type*>, |
508 | is_same<_UP_pointer, _UP_element_type*>, |
509 | is_convertible<_UP_element_type(*)[], element_type(*)[]> |
510 | >; |
511 | |
512 | // helper template for detecting a safe conversion from a raw pointer |
513 | template<typename _Up> |
514 | using __safe_conversion_raw = __and_< |
515 | __or_<__or_<is_same<_Up, pointer>, |
516 | is_same<_Up, nullptr_t>>, |
517 | __and_<is_pointer<_Up>, |
518 | is_same<pointer, element_type*>, |
519 | is_convertible< |
520 | typename remove_pointer<_Up>::type(*)[], |
521 | element_type(*)[]> |
522 | > |
523 | > |
524 | >; |
525 | |
526 | // Constructors. |
527 | |
528 | /// Default constructor, creates a unique_ptr that owns nothing. |
529 | template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> |
530 | constexpr unique_ptr() noexcept |
531 | : _M_t() |
532 | { } |
533 | |
534 | /** Takes ownership of a pointer. |
535 | * |
536 | * @param __p A pointer to an array of a type safely convertible |
537 | * to an array of @c element_type |
538 | * |
539 | * The deleter will be value-initialized. |
540 | */ |
541 | template<typename _Up, |
542 | typename _Vp = _Dp, |
543 | typename = _DeleterConstraint<_Vp>, |
544 | typename = typename enable_if< |
545 | __safe_conversion_raw<_Up>::value, bool>::type> |
546 | explicit |
547 | unique_ptr(_Up __p) noexcept |
548 | : _M_t(__p) |
549 | { } |
550 | |
551 | /** Takes ownership of a pointer. |
552 | * |
553 | * @param __p A pointer to an array of a type safely convertible |
554 | * to an array of @c element_type |
555 | * @param __d A reference to a deleter. |
556 | * |
557 | * The deleter will be initialized with @p __d |
558 | */ |
559 | template<typename _Up, typename _Del = deleter_type, |
560 | typename = _Require<__safe_conversion_raw<_Up>, |
561 | is_copy_constructible<_Del>>> |
562 | unique_ptr(_Up __p, const deleter_type& __d) noexcept |
563 | : _M_t(__p, __d) { } |
564 | |
565 | /** Takes ownership of a pointer. |
566 | * |
567 | * @param __p A pointer to an array of a type safely convertible |
568 | * to an array of @c element_type |
569 | * @param __d A reference to a deleter. |
570 | * |
571 | * The deleter will be initialized with @p std::move(__d) |
572 | */ |
573 | template<typename _Up, typename _Del = deleter_type, |
574 | typename = _Require<__safe_conversion_raw<_Up>, |
575 | is_move_constructible<_Del>>> |
576 | unique_ptr(_Up __p, |
577 | __enable_if_t<!is_lvalue_reference<_Del>::value, |
578 | _Del&&> __d) noexcept |
579 | : _M_t(std::move(__p), std::move(__d)) |
580 | { } |
581 | |
582 | template<typename _Up, typename _Del = deleter_type, |
583 | typename _DelUnref = typename remove_reference<_Del>::type, |
584 | typename = _Require<__safe_conversion_raw<_Up>>> |
585 | unique_ptr(_Up, |
586 | __enable_if_t<is_lvalue_reference<_Del>::value, |
587 | _DelUnref&&>) = delete; |
588 | |
589 | /// Move constructor. |
590 | unique_ptr(unique_ptr&&) = default; |
591 | |
592 | /// Creates a unique_ptr that owns nothing. |
593 | template<typename _Del = _Dp, typename = _DeleterConstraint<_Del>> |
594 | constexpr unique_ptr(nullptr_t) noexcept |
595 | : _M_t() |
596 | { } |
597 | |
598 | template<typename _Up, typename _Ep, typename = _Require< |
599 | __safe_conversion_up<_Up, _Ep>, |
600 | typename conditional<is_reference<_Dp>::value, |
601 | is_same<_Ep, _Dp>, |
602 | is_convertible<_Ep, _Dp>>::type>> |
603 | unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept |
604 | : _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter())) |
605 | { } |
606 | |
607 | /// Destructor, invokes the deleter if the stored pointer is not null. |
608 | ~unique_ptr() |
609 | { |
610 | auto& __ptr = _M_t._M_ptr(); |
611 | if (__ptr != nullptr) |
612 | get_deleter()(__ptr); |
613 | __ptr = pointer(); |
614 | } |
615 | |
616 | // Assignment. |
617 | |
618 | /** @brief Move assignment operator. |
619 | * |
620 | * Invokes the deleter if this object owns a pointer. |
621 | */ |
622 | unique_ptr& |
623 | operator=(unique_ptr&&) = default; |
624 | |
625 | /** @brief Assignment from another type. |
626 | * |
627 | * @param __u The object to transfer ownership from, which owns a |
628 | * convertible pointer to an array object. |
629 | * |
630 | * Invokes the deleter if this object owns a pointer. |
631 | */ |
632 | template<typename _Up, typename _Ep> |
633 | typename |
634 | enable_if<__and_<__safe_conversion_up<_Up, _Ep>, |
635 | is_assignable<deleter_type&, _Ep&&> |
636 | >::value, |
637 | unique_ptr&>::type |
638 | operator=(unique_ptr<_Up, _Ep>&& __u) noexcept |
639 | { |
640 | reset(__u.release()); |
641 | get_deleter() = std::forward<_Ep>(__u.get_deleter()); |
642 | return *this; |
643 | } |
644 | |
645 | /// Reset the %unique_ptr to empty, invoking the deleter if necessary. |
646 | unique_ptr& |
647 | operator=(nullptr_t) noexcept |
648 | { |
649 | reset(); |
650 | return *this; |
651 | } |
652 | |
653 | // Observers. |
654 | |
655 | /// Access an element of owned array. |
656 | typename std::add_lvalue_reference<element_type>::type |
657 | operator[](size_t __i) const |
658 | { |
659 | __glibcxx_assert(get() != pointer()); |
660 | return get()[__i]; |
661 | } |
662 | |
663 | /// Return the stored pointer. |
664 | pointer |
665 | get() const noexcept |
666 | { return _M_t._M_ptr(); } |
667 | |
668 | /// Return a reference to the stored deleter. |
669 | deleter_type& |
670 | get_deleter() noexcept |
671 | { return _M_t._M_deleter(); } |
672 | |
673 | /// Return a reference to the stored deleter. |
674 | const deleter_type& |
675 | get_deleter() const noexcept |
676 | { return _M_t._M_deleter(); } |
677 | |
678 | /// Return @c true if the stored pointer is not null. |
679 | explicit operator bool() const noexcept |
680 | { return get() == pointer() ? false : true; } |
681 | |
682 | // Modifiers. |
683 | |
684 | /// Release ownership of any stored pointer. |
685 | pointer |
686 | release() noexcept |
687 | { return _M_t.release(); } |
688 | |
689 | /** @brief Replace the stored pointer. |
690 | * |
691 | * @param __p The new pointer to store. |
692 | * |
693 | * The deleter will be invoked if a pointer is already owned. |
694 | */ |
695 | template <typename _Up, |
696 | typename = _Require< |
697 | __or_<is_same<_Up, pointer>, |
698 | __and_<is_same<pointer, element_type*>, |
699 | is_pointer<_Up>, |
700 | is_convertible< |
701 | typename remove_pointer<_Up>::type(*)[], |
702 | element_type(*)[] |
703 | > |
704 | > |
705 | > |
706 | >> |
707 | void |
708 | reset(_Up __p) noexcept |
709 | { _M_t.reset(std::move(__p)); } |
710 | |
711 | void reset(nullptr_t = nullptr) noexcept |
712 | { reset(pointer()); } |
713 | |
714 | /// Exchange the pointer and deleter with another object. |
715 | void |
716 | swap(unique_ptr& __u) noexcept |
717 | { |
718 | static_assert(__is_swappable<_Dp>::value, "deleter must be swappable"); |
719 | _M_t.swap(__u._M_t); |
720 | } |
721 | |
722 | // Disable copy from lvalue. |
723 | unique_ptr(const unique_ptr&) = delete; |
724 | unique_ptr& operator=(const unique_ptr&) = delete; |
725 | }; |
726 | |
727 | /// @relates unique_ptr @{ |
728 | |
729 | /// Swap overload for unique_ptr |
730 | template<typename _Tp, typename _Dp> |
731 | inline |
732 | #if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
733 | // Constrained free swap overload, see p0185r1 |
734 | typename enable_if<__is_swappable<_Dp>::value>::type |
735 | #else |
736 | void |
737 | #endif |
738 | swap(unique_ptr<_Tp, _Dp>& __x, |
739 | unique_ptr<_Tp, _Dp>& __y) noexcept |
740 | { __x.swap(__y); } |
741 | |
742 | #if __cplusplus201703L > 201402L || !defined(__STRICT_ANSI__1) // c++1z or gnu++11 |
743 | template<typename _Tp, typename _Dp> |
744 | typename enable_if<!__is_swappable<_Dp>::value>::type |
745 | swap(unique_ptr<_Tp, _Dp>&, |
746 | unique_ptr<_Tp, _Dp>&) = delete; |
747 | #endif |
748 | |
749 | /// Equality operator for unique_ptr objects, compares the owned pointers |
750 | template<typename _Tp, typename _Dp, |
751 | typename _Up, typename _Ep> |
752 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
753 | operator==(const unique_ptr<_Tp, _Dp>& __x, |
754 | const unique_ptr<_Up, _Ep>& __y) |
755 | { return __x.get() == __y.get(); } |
756 | |
757 | /// unique_ptr comparison with nullptr |
758 | template<typename _Tp, typename _Dp> |
759 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
760 | operator==(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept |
761 | { return !__x; } |
762 | |
763 | #ifndef __cpp_lib_three_way_comparison |
764 | /// unique_ptr comparison with nullptr |
765 | template<typename _Tp, typename _Dp> |
766 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
767 | operator==(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept |
768 | { return !__x; } |
769 | |
770 | /// Inequality operator for unique_ptr objects, compares the owned pointers |
771 | template<typename _Tp, typename _Dp, |
772 | typename _Up, typename _Ep> |
773 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
774 | operator!=(const unique_ptr<_Tp, _Dp>& __x, |
775 | const unique_ptr<_Up, _Ep>& __y) |
776 | { return __x.get() != __y.get(); } |
777 | |
778 | /// unique_ptr comparison with nullptr |
779 | template<typename _Tp, typename _Dp> |
780 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
781 | operator!=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) noexcept |
782 | { return (bool)__x; } |
783 | |
784 | /// unique_ptr comparison with nullptr |
785 | template<typename _Tp, typename _Dp> |
786 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
787 | operator!=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) noexcept |
788 | { return (bool)__x; } |
789 | #endif // three way comparison |
790 | |
791 | /// Relational operator for unique_ptr objects, compares the owned pointers |
792 | template<typename _Tp, typename _Dp, |
793 | typename _Up, typename _Ep> |
794 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
795 | operator<(const unique_ptr<_Tp, _Dp>& __x, |
796 | const unique_ptr<_Up, _Ep>& __y) |
797 | { |
798 | typedef typename |
799 | std::common_type<typename unique_ptr<_Tp, _Dp>::pointer, |
800 | typename unique_ptr<_Up, _Ep>::pointer>::type _CT; |
801 | return std::less<_CT>()(__x.get(), __y.get()); |
802 | } |
803 | |
804 | /// unique_ptr comparison with nullptr |
805 | template<typename _Tp, typename _Dp> |
806 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
807 | operator<(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
808 | { |
809 | return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), |
810 | nullptr); |
811 | } |
812 | |
813 | /// unique_ptr comparison with nullptr |
814 | template<typename _Tp, typename _Dp> |
815 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
816 | operator<(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
817 | { |
818 | return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, |
819 | __x.get()); |
820 | } |
821 | |
822 | /// Relational operator for unique_ptr objects, compares the owned pointers |
823 | template<typename _Tp, typename _Dp, |
824 | typename _Up, typename _Ep> |
825 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
826 | operator<=(const unique_ptr<_Tp, _Dp>& __x, |
827 | const unique_ptr<_Up, _Ep>& __y) |
828 | { return !(__y < __x); } |
829 | |
830 | /// unique_ptr comparison with nullptr |
831 | template<typename _Tp, typename _Dp> |
832 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
833 | operator<=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
834 | { return !(nullptr < __x); } |
835 | |
836 | /// unique_ptr comparison with nullptr |
837 | template<typename _Tp, typename _Dp> |
838 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
839 | operator<=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
840 | { return !(__x < nullptr); } |
841 | |
842 | /// Relational operator for unique_ptr objects, compares the owned pointers |
843 | template<typename _Tp, typename _Dp, |
844 | typename _Up, typename _Ep> |
845 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
846 | operator>(const unique_ptr<_Tp, _Dp>& __x, |
847 | const unique_ptr<_Up, _Ep>& __y) |
848 | { return (__y < __x); } |
849 | |
850 | /// unique_ptr comparison with nullptr |
851 | template<typename _Tp, typename _Dp> |
852 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
853 | operator>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
854 | { |
855 | return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(nullptr, |
856 | __x.get()); |
857 | } |
858 | |
859 | /// unique_ptr comparison with nullptr |
860 | template<typename _Tp, typename _Dp> |
861 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
862 | operator>(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
863 | { |
864 | return std::less<typename unique_ptr<_Tp, _Dp>::pointer>()(__x.get(), |
865 | nullptr); |
866 | } |
867 | |
868 | /// Relational operator for unique_ptr objects, compares the owned pointers |
869 | template<typename _Tp, typename _Dp, |
870 | typename _Up, typename _Ep> |
871 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
872 | operator>=(const unique_ptr<_Tp, _Dp>& __x, |
873 | const unique_ptr<_Up, _Ep>& __y) |
874 | { return !(__x < __y); } |
875 | |
876 | /// unique_ptr comparison with nullptr |
877 | template<typename _Tp, typename _Dp> |
878 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
879 | operator>=(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
880 | { return !(__x < nullptr); } |
881 | |
882 | /// unique_ptr comparison with nullptr |
883 | template<typename _Tp, typename _Dp> |
884 | _GLIBCXX_NODISCARD[[__nodiscard__]] inline bool |
885 | operator>=(nullptr_t, const unique_ptr<_Tp, _Dp>& __x) |
886 | { return !(nullptr < __x); } |
887 | |
888 | #ifdef __cpp_lib_three_way_comparison |
889 | template<typename _Tp, typename _Dp, typename _Up, typename _Ep> |
890 | requires three_way_comparable_with<typename unique_ptr<_Tp, _Dp>::pointer, |
891 | typename unique_ptr<_Up, _Ep>::pointer> |
892 | inline |
893 | compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer, |
894 | typename unique_ptr<_Up, _Ep>::pointer> |
895 | operator<=>(const unique_ptr<_Tp, _Dp>& __x, |
896 | const unique_ptr<_Up, _Ep>& __y) |
897 | { return compare_three_way()(__x.get(), __y.get()); } |
898 | |
899 | template<typename _Tp, typename _Dp> |
900 | requires three_way_comparable<typename unique_ptr<_Tp, _Dp>::pointer> |
901 | inline |
902 | compare_three_way_result_t<typename unique_ptr<_Tp, _Dp>::pointer> |
903 | operator<=>(const unique_ptr<_Tp, _Dp>& __x, nullptr_t) |
904 | { |
905 | using pointer = typename unique_ptr<_Tp, _Dp>::pointer; |
906 | return compare_three_way()(__x.get(), static_cast<pointer>(nullptr)); |
907 | } |
908 | #endif |
909 | // @} relates unique_ptr |
910 | |
911 | /// @cond undocumented |
912 | template<typename _Up, typename _Ptr = typename _Up::pointer, |
913 | bool = __poison_hash<_Ptr>::__enable_hash_call> |
914 | struct __uniq_ptr_hash |
915 | #if ! _GLIBCXX_INLINE_VERSION0 |
916 | : private __poison_hash<_Ptr> |
917 | #endif |
918 | { |
919 | size_t |
920 | operator()(const _Up& __u) const |
921 | noexcept(noexcept(std::declval<hash<_Ptr>>()(std::declval<_Ptr>()))) |
922 | { return hash<_Ptr>()(__u.get()); } |
923 | }; |
924 | |
925 | template<typename _Up, typename _Ptr> |
926 | struct __uniq_ptr_hash<_Up, _Ptr, false> |
927 | : private __poison_hash<_Ptr> |
928 | { }; |
929 | /// @endcond |
930 | |
931 | /// std::hash specialization for unique_ptr. |
932 | template<typename _Tp, typename _Dp> |
933 | struct hash<unique_ptr<_Tp, _Dp>> |
934 | : public __hash_base<size_t, unique_ptr<_Tp, _Dp>>, |
935 | public __uniq_ptr_hash<unique_ptr<_Tp, _Dp>> |
936 | { }; |
937 | |
938 | #if __cplusplus201703L >= 201402L |
939 | /// @relates unique_ptr @{ |
940 | #define __cpp_lib_make_unique201304 201304 |
941 | |
942 | /// @cond undocumented |
943 | |
944 | template<typename _Tp> |
945 | struct _MakeUniq |
946 | { typedef unique_ptr<_Tp> __single_object; }; |
947 | |
948 | template<typename _Tp> |
949 | struct _MakeUniq<_Tp[]> |
950 | { typedef unique_ptr<_Tp[]> __array; }; |
951 | |
952 | template<typename _Tp, size_t _Bound> |
953 | struct _MakeUniq<_Tp[_Bound]> |
954 | { struct __invalid_type { }; }; |
955 | |
956 | /// @endcond |
957 | |
958 | /// std::make_unique for single objects |
959 | template<typename _Tp, typename... _Args> |
960 | inline typename _MakeUniq<_Tp>::__single_object |
961 | make_unique(_Args&&... __args) |
962 | { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); } |
963 | |
964 | /// std::make_unique for arrays of unknown bound |
965 | template<typename _Tp> |
966 | inline typename _MakeUniq<_Tp>::__array |
967 | make_unique(size_t __num) |
968 | { return unique_ptr<_Tp>(new remove_extent_t<_Tp>[__num]()); } |
969 | |
970 | /// Disable std::make_unique for arrays of known bound |
971 | template<typename _Tp, typename... _Args> |
972 | inline typename _MakeUniq<_Tp>::__invalid_type |
973 | make_unique(_Args&&...) = delete; |
974 | // @} relates unique_ptr |
975 | #endif // C++14 |
976 | |
977 | #if __cplusplus201703L > 201703L && __cpp_concepts |
978 | // _GLIBCXX_RESOLVE_LIB_DEFECTS |
979 | // 2948. unique_ptr does not define operator<< for stream output |
980 | /// Stream output operator for unique_ptr |
981 | template<typename _CharT, typename _Traits, typename _Tp, typename _Dp> |
982 | inline basic_ostream<_CharT, _Traits>& |
983 | operator<<(basic_ostream<_CharT, _Traits>& __os, |
984 | const unique_ptr<_Tp, _Dp>& __p) |
985 | requires requires { __os << __p.get(); } |
986 | { |
987 | __os << __p.get(); |
988 | return __os; |
989 | } |
990 | #endif // C++20 |
991 | |
992 | // @} group pointer_abstractions |
993 | |
994 | #if __cplusplus201703L >= 201703L |
995 | namespace __detail::__variant |
996 | { |
997 | template<typename> struct _Never_valueless_alt; // see <variant> |
998 | |
999 | // Provide the strong exception-safety guarantee when emplacing a |
1000 | // unique_ptr into a variant. |
1001 | template<typename _Tp, typename _Del> |
1002 | struct _Never_valueless_alt<std::unique_ptr<_Tp, _Del>> |
1003 | : std::true_type |
1004 | { }; |
1005 | } // namespace __detail::__variant |
1006 | #endif // C++17 |
1007 | |
1008 | _GLIBCXX_END_NAMESPACE_VERSION |
1009 | } // namespace |
1010 | |
1011 | #endif /* _UNIQUE_PTR_H */ |