1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include <algorithm>
25 #include <iterator>
26
27 #ifndef INCLUDED_DOCTOK_EXCEPTIONS
28 #include <resourcemodel/exceptions.hxx>
29 #endif
30 #include <WW8PieceTableImpl.hxx>
31 #include <WW8Clx.hxx>
32
33 namespace writerfilter {
34 namespace doctok
35 {
36 using namespace ::std;
37
operator <<(ostream & o,const WW8PieceTable & rPieceTable)38 ostream & operator << (ostream & o, const WW8PieceTable & rPieceTable)
39 {
40 rPieceTable.dump(o);
41
42 return o;
43 }
44
WW8PieceTableImpl(WW8Stream & rStream,sal_uInt32 nOffset,sal_uInt32 nCount)45 WW8PieceTableImpl::WW8PieceTableImpl(WW8Stream & rStream,
46 sal_uInt32 nOffset,
47 sal_uInt32 nCount)
48 {
49 WW8Clx aClx(rStream, nOffset, nCount);
50
51 sal_uInt32 nPieceCount = aClx.getPieceCount();
52
53 if (nPieceCount > 0)
54 {
55 for (sal_uInt32 n = 0; n < nPieceCount; n++)
56 {
57 Cp aCp(aClx.getCp(n));
58 Fc aFc(aClx.getFc(n), aClx.isComplexFc(n));
59
60 CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
61
62 mEntries.push_back(aCpAndFc);
63 }
64
65 CpAndFc aBack = mEntries.back();
66 Cp aCp(aClx.getCp(aClx.getPieceCount()));
67 Fc aFc(aBack.getFc() + (aCp - aBack.getCp()));
68
69 CpAndFc aCpAndFc(aCp, aFc, PROP_DOC);
70
71 mEntries.push_back(aCpAndFc);
72 }
73 }
74
getCount() const75 sal_uInt32 WW8PieceTableImpl::getCount() const
76 {
77 return mEntries.size();
78 }
79
80 WW8PieceTableImpl::tEntries::const_iterator
findCp(const Cp & rCp) const81 WW8PieceTableImpl::findCp(const Cp & rCp) const
82 {
83 tEntries::const_iterator aResult = mEntries.end();
84 tEntries::const_iterator aEnd = mEntries.end();
85
86 for (tEntries::const_iterator aIt = mEntries.begin(); aIt != aEnd;
87 aIt++)
88 {
89 if (aIt->getCp() <= rCp)
90 {
91 aResult = aIt;
92
93 //break;
94 }
95 }
96
97 return aResult;
98 }
99
100 WW8PieceTableImpl::tEntries::const_iterator
findFc(const Fc & rFc) const101 WW8PieceTableImpl::findFc(const Fc & rFc) const
102 {
103 tEntries::const_iterator aResult = mEntries.end();
104 tEntries::const_iterator aEnd = mEntries.end();
105
106 if (mEntries.size() > 0)
107 {
108 if (rFc < mEntries.begin()->getFc())
109 aResult = mEntries.begin();
110 else
111 {
112 for (tEntries::const_iterator aIt = mEntries.begin();
113 aIt != aEnd; aIt++)
114 {
115 if (aIt->getFc() <= rFc)
116 {
117 tEntries::const_iterator aItNext = aIt;
118 aItNext++;
119
120 if (aItNext != aEnd)
121 {
122 sal_uInt32 nOffset = rFc.get() - aIt->getFc().get();
123 sal_uInt32 nLength = aItNext->getCp() - aIt->getCp();
124
125 if (! aIt->isComplex())
126 nLength *= 2;
127
128 if (nOffset < nLength)
129 {
130 aResult = aIt;
131
132 break;
133 }
134 }
135
136 }
137 }
138 }
139 }
140
141 return aResult;
142 }
143
getFirstCp() const144 Cp WW8PieceTableImpl::getFirstCp() const
145 {
146 Cp aResult;
147
148 if (getCount() > 0)
149 aResult = getCp(0);
150 else
151 throw ExceptionNotFound("WW8PieceTableImpl::getFirstCp");
152
153 return aResult;
154 }
155
getFirstFc() const156 Fc WW8PieceTableImpl::getFirstFc() const
157 {
158 Fc aResult;
159
160 if (getCount() > 0)
161 aResult = getFc(0);
162 else
163 throw ExceptionNotFound(" WW8PieceTableImpl::getFirstFc");
164
165 return aResult;
166 }
167
getLastCp() const168 Cp WW8PieceTableImpl::getLastCp() const
169 {
170 Cp aResult;
171
172 if (getCount() > 0)
173 aResult = getCp(getCount() - 1);
174 else
175 throw ExceptionNotFound("WW8PieceTableImpl::getLastCp");
176
177 return aResult;
178 }
179
getLastFc() const180 Fc WW8PieceTableImpl::getLastFc() const
181 {
182 Fc aResult;
183
184 if (getCount() > 0)
185 aResult = getFc(getCount() - 1);
186 else
187 throw ExceptionNotFound("WW8PieceTableImpl::getLastFc");
188
189 return aResult;
190 }
191
getCp(sal_uInt32 nIndex) const192 Cp WW8PieceTableImpl::getCp(sal_uInt32 nIndex) const
193 {
194 return mEntries[nIndex].getCp();
195 }
196
getFc(sal_uInt32 nIndex) const197 Fc WW8PieceTableImpl::getFc(sal_uInt32 nIndex) const
198 {
199 return mEntries[nIndex].getFc();
200 }
201
fc2cp(const Fc & rFc) const202 Cp WW8PieceTableImpl::fc2cp(const Fc & rFc) const
203 {
204 Cp cpResult;
205
206 if (mEntries.size() > 0)
207 {
208 Fc aFc;
209
210 if (rFc < mEntries.begin()->getFc())
211 aFc = mEntries.begin()->getFc();
212 else
213 aFc = rFc;
214
215 tEntries::const_iterator aIt = findFc(aFc);
216
217 if (aIt != mEntries.end())
218 {
219 cpResult = aIt->getCp() + (aFc - aIt->getFc());
220 }
221 else
222 throw ExceptionNotFound("WW8PieceTableImpl::fc2cp: " + aFc.toString());
223 }
224
225 return cpResult;
226 }
227
cp2fc(const Cp & rCp) const228 Fc WW8PieceTableImpl::cp2fc(const Cp & rCp) const
229 {
230 Fc aResult;
231
232 Cp2FcHashMap_t::iterator aItCp = mCp2FcCache.find(rCp);
233
234 if (aItCp == mCp2FcCache.end())
235 {
236 tEntries::const_iterator aIt = findCp(rCp);
237
238 if (aIt != mEntries.end())
239 {
240 aResult = aIt->getFc() + (rCp - aIt->getCp());
241 mCp2FcCache[rCp] = aResult;
242 }
243 else
244 throw ExceptionNotFound
245 ("WW8PieceTableImpl::cp2fc: " + rCp.toString());
246 }
247 else
248 aResult = mCp2FcCache[rCp];
249
250 return aResult;
251 }
252
isComplex(const Cp & rCp) const253 bool WW8PieceTableImpl::isComplex(const Cp & rCp) const
254 {
255 bool bResult = false;
256
257 tEntries::const_iterator aIt = findCp(rCp);
258
259 if (aIt != mEntries.end())
260 bResult = aIt->isComplex();
261
262 return bResult;
263 }
264
isComplex(const Fc & rFc) const265 bool WW8PieceTableImpl::isComplex(const Fc & rFc) const
266 {
267 bool bResult = false;
268
269 tEntries::const_iterator aIt = findFc(rFc);
270
271 if (aIt != mEntries.end())
272 bResult = aIt->isComplex();
273
274 return bResult;
275 }
276
createCpAndFc(const Cp & rCp,PropertyType eType) const277 CpAndFc WW8PieceTableImpl::createCpAndFc
278 (const Cp & rCp, PropertyType eType) const
279 {
280 return CpAndFc(rCp, cp2fc(rCp), eType);
281 }
282
createCpAndFc(const Fc & rFc,PropertyType eType) const283 CpAndFc WW8PieceTableImpl::createCpAndFc
284 (const Fc & rFc, PropertyType eType) const
285 {
286 return CpAndFc(fc2cp(rFc), rFc, eType);
287 }
288
dump(ostream & o) const289 void WW8PieceTableImpl::dump(ostream & o) const
290 {
291 o << "<piecetable>" << endl;
292 copy(mEntries.begin(), mEntries.end(), ostream_iterator<CpAndFc>(o, "\n"));
293 o << "</piecetable>" << endl;
294 }
295 }}
296