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 #ifndef INCLUDED_PLCF_HXX
25 #define INCLUDED_PLCF_HXX
26
27 #include <boost/shared_ptr.hpp>
28 #include <WW8StructBase.hxx>
29
30 namespace writerfilter {
31 namespace doctok
32 {
33
34 class Empty
35 {
36 public:
37 typedef boost::shared_ptr<Empty> Pointer_t;
38
Empty()39 Empty() {}
~Empty()40 virtual ~Empty() {}
41
getSize()42 sal_uInt32 getSize() { return 0; }
43 };
44
45 template <class T>
46 /**
47 Plex in File
48
49 A PLCF is a concatenation of two arrays. The first array contains
50 file character positions. The second array contains elements of
51 type T. If the first array contains N elements, the second contains
52 N - 1 elements. The N-th element in the first array corresponds to
53 the N-th element of the second array.
54
55 The second array is referred to as the payload.
56 */
57 class PLCF : public WW8StructBase
58 {
59 /// number of entries
60 sal_uInt32 nEntryCount;
61
62 /// offset to payload
63 sal_uInt32 nPayloadOffset;
64
65 /// internal method to calculate the number of entries
66 sal_uInt32 getEntryCount_() const;
67
68 public:
69 typedef boost::shared_ptr< PLCF< T > > Pointer_t;
70
PLCF(sal_uInt32 nLength)71 PLCF(sal_uInt32 nLength)
72 : WW8StructBase(nLength), nEntryCount(getEntryCount_()),
73 nPayloadOffset((nEntryCount + 1) * 4)
74 {
75 }
76
PLCF(WW8Stream & rStream,sal_Int32 nOffset,sal_Int32 nCount)77 PLCF(WW8Stream & rStream,
78 sal_Int32 nOffset, sal_Int32 nCount)
79 : WW8StructBase(rStream, nOffset, nCount),
80 nEntryCount(getEntryCount_()),
81 nPayloadOffset((nEntryCount + 1) * 4)
82 {
83 }
84
PLCF(const Sequence & rSequence)85 PLCF(const Sequence & rSequence)
86 : WW8StructBase(rSequence), nEntryCount(getEntryCount_()),
87 nPayloadOffset((nEntryCount + 1) * 4)
88 {
89 }
90
91 /**
92 Return the number of elements in the PLCF-
93 */
getEntryCount() const94 sal_uInt32 getEntryCount() const { return nEntryCount; }
95
96 /**
97 Return the file character position of a certain element.
98
99 @param nIndex the index of the element
100 */
101 sal_uInt32 getFc(sal_uInt32 nIndex) const;
102
103 /**
104 Return a C++ pointer to a certain payload entry.
105
106 @param nIndex the index of the element
107 */
108 T * getEntryPointer(sal_uInt32 nIndex) const;
109
110 /**
111 Return a shared pointer to a certain payload element.
112
113 @param nIndex the index of the element
114 */
115 typename T::Pointer_t getEntry(sal_uInt32 nIndex) const;
116
117 /**
118 Return a C++ pointer a certain payload element.
119
120 @param nFc the file character position of the element
121 */
122 T * getEntryByFc(sal_uInt32 nFc) const;
123
124 virtual void dump(OutputWithDepth<string> & out) const;
125 };
126
127 template <class T>
getEntryCount_() const128 sal_uInt32 PLCF<T>::getEntryCount_() const
129 {
130 return (getCount() - 4) / (T::getSize() + 4);
131 }
132
133 template <class T>
getFc(sal_uInt32 nIndex) const134 sal_uInt32 PLCF<T>::getFc(sal_uInt32 nIndex) const
135 {
136 return getU32(nIndex * 4);
137 }
138
139 template <class T>
getEntryPointer(sal_uInt32 nIndex) const140 T * PLCF<T>::getEntryPointer(sal_uInt32 nIndex) const
141 {
142 return new T(mSequence, nPayloadOffset + nIndex * T::getSize(),
143 T::getSize());
144 }
145
146 template <class T>
getEntry(sal_uInt32 nIndex) const147 typename T::Pointer_t PLCF<T>::getEntry(sal_uInt32 nIndex) const
148 {
149 typename T::Pointer_t pResult(getEntryPointer(nIndex));
150
151 return pResult;
152 }
153
154
155 template <class T>
getEntryByFc(sal_uInt32 nFc) const156 T * PLCF<T>::getEntryByFc(sal_uInt32 nFc) const
157 {
158 T * pResult = NULL;
159
160 sal_uInt32 n = getEntryCount();
161
162 while (getFc(n) > nFc)
163 n--;
164
165 pResult = getEntryPointer(n);
166
167 return pResult;
168 }
169
170 template <class T>
dump(OutputWithDepth<string> & output_) const171 void PLCF<T>::dump(OutputWithDepth<string> & output_) const
172 {
173 output_.addItem("<plcf>");
174 WW8StructBase::dump(output_);
175
176 sal_uInt32 nCount = getEntryCount();
177 for (sal_uInt32 n = 0; n < nCount; ++n)
178 {
179 Fc aFc = getFc(n);
180 typename T::Pointer_t pT = getEntry(n);
181
182 output_.addItem("<plcfentry cpandfc=\"" + aFc.toString() + "\">");
183 pT->dump(output_);
184 output_.addItem("</plcfentry>");
185 }
186 output_.addItem("</plcf>>");
187 }
188
189 }}
190
191 #endif // INCLUDED_PLCF_HXX
192