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