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 "WW8FKPImpl.hxx"
25 #include "WW8PropertySetImpl.hxx"
26 
27 namespace writerfilter {
28 namespace doctok
29 {
30 #if 0
31 sal_uInt32 WW8FKPImpl::getIndex(const Fc & rFc) const
32 {
33     sal_uInt32 nLeft = 0;
34     sal_uInt32 nRight = getEntryCount();
35 
36     while (nRight - nLeft > 1)
37     {
38         sal_uInt32 nMiddle = (nLeft + nRight) / 2;
39         Fc aFcMiddle = getFc(nMiddle);
40 
41         if (! (rFc < aFcMiddle))
42         {
43             nLeft = nMiddle;
44         }
45         else
46         {
47             nRight = nMiddle;
48         }
49     }
50 
51     return nLeft;
52 }
53 #else
getIndex(const Fc & rFc) const54 sal_uInt32 WW8FKPImpl::getIndex(const Fc & rFc) const
55 {
56     sal_uInt32 nResult = getEntryCount();
57 
58     while (rFc < getFc(nResult))
59         nResult--;
60 
61     return nResult;
62 }
63 #endif
64 
65 
getProperties(const Fc & rFc) const66 writerfilter::Reference<Properties>::Pointer_t WW8CHPFKPImpl::getProperties(const Fc & rFc) const
67 {
68     writerfilter::Reference<Properties>::Pointer_t pResult;
69 
70     sal_uInt32 n = getIndex(rFc);
71 
72     sal_uInt16 nOffset = 2 * getU8(getRgb() + n);
73 
74     if (nOffset > getRgb() + getEntryCount())
75     {
76         sal_uInt16 nCbChpx = getU8(nOffset);
77 
78         if (nCbChpx > 1 && nOffset + nCbChpx + 1 <= 511)
79         {
80             pResult = writerfilter::Reference<Properties>::Pointer_t
81                 (new WW8PropertySetImpl(*this, nOffset + 1, nCbChpx));
82         }
83     }
84 #if 0
85     else
86     {
87         clog << "outsider!!!" << endl;
88     }
89 #endif
90 
91     return pResult;
92 }
93 
dump(OutputWithDepth<string> & o) const94 void WW8CHPFKPImpl::dump(OutputWithDepth<string> & o) const
95 {
96     o.addItem("<fkp type='CHP'>");
97 
98     sal_uInt32 nCount = getEntryCount();
99     for (sal_uInt32 n = 0; n < nCount; ++n)
100     {
101         char sBuffer[256];
102 
103         snprintf(sBuffer, sizeof(sBuffer),
104                  "<fkpentry fc='%" SAL_PRIxUINT32 "' offsetInFkp='%x'/>",
105                  getFc(n).get(), 2 * getU8(getRgb() + n));
106 
107         o.addItem(sBuffer);
108     }
109 
110     WW8StructBase::dump(o);
111     o.addItem("</fkp>");
112 }
113 
114 writerfilter::Reference<Properties>::Pointer_t
getProperties(const Fc & rFc) const115 WW8PAPFKPImpl::getProperties(const Fc & rFc) const
116 {
117     writerfilter::Reference<Properties>::Pointer_t pResult;
118 
119     sal_uInt32 n = getIndex(rFc);
120 
121     sal_uInt16 nOffset = 2 * getU8(getRgb() + n * 13);
122 
123     if (nOffset != 0)
124     {
125         if (nOffset > getRgb() + getEntryCount() * 13)
126         {
127             sal_uInt32 nOffsetIStd = nOffset + 1;
128             sal_uInt16 nCbPapx = getU8(nOffset) * 2;
129 
130             if (nCbPapx == 0)
131             {
132                 nOffsetIStd = nOffset + 2;
133                 nCbPapx = getU8(nOffset + 1) * 2 + 2;
134             }
135 
136             sal_uInt32 nOffsetEnd = nOffset + nCbPapx;
137             //sal_uInt32 nOffsetSprms = nOffsetIStd + 2;
138 
139             if (nCbPapx > 1 && nOffset + nCbPapx <= 511)
140             {
141                 pResult = writerfilter::Reference<Properties>::Pointer_t
142                     (new WW8PropertySetImpl(*this, nOffsetIStd,
143                                             nOffsetEnd - nOffsetIStd,
144                                             true));
145             }
146         }
147 #if 0
148         else
149         {
150             clog << "outsider!!!" << endl;
151         }
152 #endif
153     }
154 
155     return pResult;
156 }
157 
dump(OutputWithDepth<string> & o) const158 void WW8PAPFKPImpl::dump(OutputWithDepth<string> & o) const
159 {
160     o.addItem("<fkp type='PAP'>");
161 
162     sal_uInt32 nCount = getEntryCount();
163     for (sal_uInt32 n = 0; n < nCount; ++n)
164     {
165         char sBuffer[256];
166 
167         snprintf(sBuffer, sizeof(sBuffer),
168                  "<fkpentry fc='%" SAL_PRIxUINT32 "' offsetInFKP='%x'/>",
169                  getFc(n).get(), 2 * getU8(getRgb() + n * 13));
170 
171         o.addItem(sBuffer);
172     }
173 
174     WW8StructBase::dump(o);
175 
176     o.addItem("</fkp>");
177 }
178 
operator <(const PageNumberAndFKP & rA,const PageNumberAndFKP & rB)179 bool operator < (const PageNumberAndFKP & rA,
180                  const PageNumberAndFKP & rB)
181 {
182     return rA.mnPageNumber < rB.mnPageNumber;
183 }
184 
~WW8FKPCache()185 WW8FKPCache::~WW8FKPCache()
186 {
187 }
188 
get(sal_uInt32 nPageNumber,bool bComplex)189 WW8FKP::Pointer_t WW8FKPCacheImpl::get(sal_uInt32 nPageNumber,
190                                        bool bComplex)
191 {
192     WW8FKP::Pointer_t pResult;
193 
194     PageNumbersAndFKPs::iterator aIt;
195     aIt = mPageNumbersAndFKPs.find
196         (PageNumberAndFKP(nPageNumber, WW8FKP::Pointer_t()));
197 
198     if (aIt != mPageNumbersAndFKPs.end())
199         pResult = aIt->getFKP();
200     else
201     {
202         if (mPageNumbersAndFKPs.size() > mnCacheSize)
203         {
204             PageNumbersAndFKPs::iterator aItDel =
205                 mPageNumbersAndFKPs.find
206                 (PageNumberAndFKP(mPageNumbers.front(),
207                                   WW8FKP::Pointer_t()));
208 
209             mPageNumbersAndFKPs.erase(aItDel);
210             mPageNumbers.pop_front();
211         }
212 
213         pResult = createFKP(nPageNumber, bComplex);
214 
215         PageNumberAndFKP aPageNumberAndFKP(nPageNumber, pResult);
216         mPageNumbersAndFKPs.insert(aPageNumberAndFKP);
217         mPageNumbers.push_back(nPageNumber);
218     }
219 
220     return pResult;
221 }
222 
createFKP(sal_uInt32 nPageNumber,bool bComplex)223 WW8FKP::Pointer_t WW8CHPFKPCacheImpl::createFKP(sal_uInt32 nPageNumber,
224                                                 bool bComplex)
225 {
226     return WW8FKP::Pointer_t(new WW8CHPFKPImpl
227                              (*mpStream, nPageNumber, bComplex));
228 }
229 
createFKP(sal_uInt32 nPageNumber,bool bComplex)230 WW8FKP::Pointer_t WW8PAPFKPCacheImpl::createFKP(sal_uInt32 nPageNumber,
231                                                 bool bComplex)
232 {
233     return WW8FKP::Pointer_t(new WW8PAPFKPImpl
234                              (*mpStream, nPageNumber, bComplex));
235 }
236 }}
237