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_WW8_STRUCT_BASE_HXX
25 #define INCLUDED_WW8_STRUCT_BASE_HXX
26 
27 #include <boost/shared_ptr.hpp>
28 #include <doctok/WW8Document.hxx>
29 #include <resourcemodel/OutputWithDepth.hxx>
30 
31 namespace writerfilter {
32 namespace doctok {
33 
34 class WW8DocumentImpl;
35 
36 /**
37    Part of a stream.
38 
39    A part can have a parent, meaning its sequence of data is a
40    subsequence of its parent's sequence of data.
41  */
42 class WW8StructBase
43 {
44 public:
45     typedef SubSequence<sal_uInt8> Sequence;
46     typedef boost::shared_ptr<WW8StructBase> Pointer_t;
47 
48 protected:
49     /**
50        Stream this part was created from.
51     */
52     ::com::sun::star::uno::Reference<com::sun::star::io::
53     XInputStream> mrStream;
54 
55     /**
56        The data.
57      */
58     mutable Sequence mSequence;
59 
60     /**
61        This part's parent.
62      */
63     WW8StructBase * mpParent;
64 
65     /**
66        This part's offset in parent.
67     */
68     sal_uInt32 mnOffsetInParent;
69 
70     /**
71        The document of this struct.
72      */
73     WW8DocumentImpl * mpDocument;
74 
75 public:
WW8StructBase(sal_Int32 nLength)76     WW8StructBase(sal_Int32 nLength)
77     : mSequence(nLength)
78     {
79     }
80 
81     /**
82        Creates a part from a steam.
83 
84        @param rStream    the stream
85        @param nOffset    offset in @a rStream to start at
86        @param nCount     count of bytes in the new part
87      */
WW8StructBase(WW8Stream & rStream,sal_Int32 nOffset,sal_Int32 nCount)88     WW8StructBase(WW8Stream & rStream,
89                   sal_Int32 nOffset, sal_Int32 nCount)
90     : mSequence(rStream.get(nOffset, nCount)), mpParent(0), mpDocument(0)
91     {
92     }
93 
94     /**
95        Creates a part from a sequence.
96 
97        @param rSequence    the sequence
98        @param nOffset    offset in @a rSequence to start at
99        @param nCount     count of bytes in the new part
100      */
WW8StructBase(const Sequence & rSequence,sal_uInt32 nOffset=0,sal_uInt32 nCount=0)101     WW8StructBase(const Sequence & rSequence, sal_uInt32 nOffset = 0,
102                   sal_uInt32 nCount = 0)
103     : mSequence(rSequence, nOffset, nCount), mpParent(0), mpDocument(0)
104     {
105     }
106 
107     /**
108        Creates a part from a parent part.
109 
110        @param pParent    the parent
111        @param nOffset    offset in @a pParent to start at
112        @param nCount     count of bytes in the new part
113      */
114     WW8StructBase(const WW8StructBase & rParent,
115                   sal_uInt32 nOffset, sal_uInt32 nCount);
116 
117     /**
118        Creates a part from a parent part.
119 
120        @param pParent    the parent
121        @param nOffset    offset in @a pParent to start at
122        @param nCount     count of bytes in the new part
123      */
WW8StructBase(WW8StructBase * pParent,sal_uInt32 nOffset,sal_uInt32 nCount)124     WW8StructBase(WW8StructBase * pParent,
125                   sal_uInt32 nOffset, sal_uInt32 nCount)
126     : mSequence(pParent->mSequence, nOffset, nCount), mpParent(pParent),
127       mnOffsetInParent(nOffset), mpDocument(pParent->getDocument())
128     {
129         if (nOffset + nCount > pParent->mSequence.getCount())
130             throw ExceptionOutOfBounds("WW8StructBase");
131     }
132 
133 
~WW8StructBase()134     virtual ~WW8StructBase()
135     {
136     }
137 
138     /**
139        Assign a part to this part.
140 
141        After assignment this part has the same content as the assigned
142        part.
143 
144        @param rSrc     part to assign
145 
146        @return this part after assignment
147      */
148     virtual WW8StructBase & Assign(const WW8StructBase & rSrc);
149 
150     /**
151        Set the document of this struct.
152      */
153     void setDocument(WW8DocumentImpl * pDocument);
154 
155     /**
156        Return the document of this struct.
157     */
158     WW8DocumentImpl * getDocument() const;
159 
160     /**
161        Return count of bytes in this part.
162      */
getCount() const163     sal_uInt32 getCount() const { return mSequence.getCount(); }
164 
165     /**
166        Return unsigned byte value at an offset.
167 
168        @param offset     offset to get value from
169      */
170     sal_uInt8 getU8(sal_uInt32 nOffset) const;
171 
172     /**
173        Return unsigned 16-bit value at an offset.
174 
175        @param offset     offset to get value from
176      */
177     sal_uInt16 getU16(sal_uInt32 nOffset) const;
178 
179     /**
180        Return unsigned 32-bit value at an offset.
181 
182        @param offset     offset to get value from
183      */
184     sal_uInt32 getU32(sal_uInt32 nOffset) const;
185 
186     /**
187        Return signed 8-bit value at an offset.
188 
189        @param offset     offset to get value from
190      */
getS8(sal_uInt32 nOffset) const191     sal_Int8 getS8(sal_uInt32 nOffset) const
192     { return (sal_Int8) getU8(nOffset); }
193 
194     /**
195        Return signed 16-bit value at an offset.
196 
197        @param offset     offset to get value from
198      */
getS16(sal_uInt32 nOffset) const199     sal_Int16 getS16(sal_uInt32 nOffset) const
200     {return (sal_Int16) getU16(nOffset); }
201 
202     /**
203        Return signed 32-bit value at an offset.
204 
205        @param offset     offset to get value from
206      */
getS32(sal_uInt32 nOffset) const207     sal_Int32 getS32(sal_uInt32 nOffset) const
208     { return (sal_Int32) getU32(nOffset); }
209 
210     /**
211        Return bit value from a 32-bit unsigned value.
212 
213        @param nValue     value to retrieve bit from
214        @param nBit       number of bit to retrieve (0 = least significant)
215      */
216     sal_Bool getBit(sal_uInt32 nValue, sal_uInt16 nBit) const;
217 
218     /**
219         Return nibble from a 32-bit unsigned value.
220 
221         @param nValue   value to retrieve nibble from (most significant bit left)
222         @param nShift   amount of bits to shift right before returning least significant nibble
223     */
224     sal_uInt8 getNibble(sal_uInt32 nValue, sal_uInt16 nShift) const;
225 
226     /**
227        Returns byte at an index.
228 
229        @param nIndex  index in this part of the byte to return
230      */
get(sal_uInt32 nIndex) const231     const sal_uInt8 * get(sal_uInt32 nIndex) const
232     { return &((mSequence.getSequence())[nIndex + mSequence.getOffset()]); }
233 
234     /**
235        Returns two byte character string starting at an offset.
236 
237        The string has to be Pascal like, e.g. the first word contains
238        the lengthof the string in characters and is followed by the
239        string's characters.
240 
241        @param nOffset    offset the string starts at
242 
243        @return  the string
244      */
245     rtl::OUString getString(sal_uInt32 nOffset) const;
246 
247     /**
248        Returns binary object for remainder of this WW8StructBase
249 
250        @param nOffset     offset where remainder starts
251      */
252     WW8StructBase * getRemainder(sal_uInt32 nOffset) const;
253 
254     /**
255        Returns two byte character string starting at an offset with a
256        given length.
257 
258        @param nOffset     offset the string starts at
259        @param nLength     number of characters in the string
260      */
261     rtl::OUString getString(sal_uInt32 nOffset, sal_uInt32) const;
262 
263     /**
264        Dump the part.
265 
266        @param o       stream to dump to
267      */
dump(OutputWithDepth<string> & o) const268     virtual void dump(OutputWithDepth<string> & o) const { mSequence.dump(o); }
269 };
270 
271 class WW8StructBaseTmpOffset
272 {
273     sal_uInt32 mnOffset;
274     WW8StructBase * mpStructBase;
275 
276 public:
277     WW8StructBaseTmpOffset(WW8StructBase * pStructBase);
278 
279     sal_uInt32 set(sal_uInt32 nOffset);
280     sal_uInt32 get() const;
281     sal_uInt32 inc(sal_uInt32 nOffset);
282 
283     operator sal_uInt32 () const;
284 };
285 
286 /**
287    Return unsigned byte from a sequence.
288 
289    @param rSeq        sequence to get value from
290    @param nOffset     offset in sequence to get value from
291  */
292 sal_uInt8 getU8(const WW8StructBase::Sequence & rSeq,  sal_uInt32 nOffset);
293 
294 /**
295    Return unsigned 16-bit value from a sequence.
296 
297    @param rSeq        sequence to get value from
298    @param nOffset     offset in sequence to get value from
299  */
300 sal_uInt16 getU16(const WW8StructBase::Sequence & rSeq, sal_uInt32 nOffset);
301 
302 /**
303    Return unsigned 32-bit value from a sequence.
304 
305    @param rSeq        sequence to get value from
306    @param nOffset     offset in sequence to get value from
307  */
308 sal_uInt32 getU32(const WW8StructBase::Sequence & rSeq, sal_uInt32 nOffset);
309 
310 }}
311 
312 #endif // INCLUDED_WW8_STRUCT_BASE_HXX
313