xref: /aoo4110/main/oox/inc/oox/ole/axbinaryreader.hxx (revision b1cdbd2c)
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 OOX_OLE_AXBINARYREADER_HXX
25 #define OOX_OLE_AXBINARYREADER_HXX
26 
27 #include <utility>
28 #include "oox/helper/binaryinputstream.hxx"
29 #include "oox/helper/refvector.hxx"
30 
31 namespace oox {
32 namespace ole {
33 
34 // ============================================================================
35 
36 /** A wrapper for a binary input stream that supports aligned read operations.
37 
38     The implementation does not support seeking back the wrapped stream. All
39     seeking operations (tell, seekTo, align) are performed relative to the
40     position of the wrapped stream at construction time of this wrapper. It is
41     possible to construct this wrapper with an unseekable input stream without
42     loosing any functionality.
43  */
44 class AxAlignedInputStream : public BinaryInputStream
45 {
46 public:
47     explicit            AxAlignedInputStream( BinaryInputStream& rInStrm );
48 
49     /** Returns the size of the data this stream represents, if the wrapped
50         stream supports the size() operation. */
51     virtual sal_Int64   size() const;
52     /** Return the current relative stream position (relative to position of
53         the wrapped stream at construction time). */
54     virtual sal_Int64   tell() const;
55     /** Seeks the stream to the passed relative position, if it is behind the
56         current position. */
57     virtual void        seek( sal_Int64 nPos );
58     /** Closes the input stream but not the wrapped stream. */
59     virtual void        close();
60 
61     /** Reads nBytes bytes to the passed sequence.
62         @return  Number of bytes really read. */
63     virtual sal_Int32   readData( StreamDataSequence& orData, sal_Int32 nBytes, size_t nAtomSize = 1 );
64     /** Reads nBytes bytes to the (existing) buffer opMem.
65         @return  Number of bytes really read. */
66     virtual sal_Int32   readMemory( void* opMem, sal_Int32 nBytes, size_t nAtomSize = 1 );
67     /** Seeks the stream forward by the passed number of bytes. */
68     virtual void        skip( sal_Int32 nBytes, size_t nAtomSize = 1 );
69 
70     /** Aligns the stream to a multiple of the passed size (relative to the
71         position of the wrapped stream at construction time). */
72     void                align( size_t nSize );
73 
74     /** Aligns the stream according to the passed type and reads an atomar value. */
75     template< typename Type >
readAligned()76     inline Type         readAligned() { align( sizeof( Type ) ); return readValue< Type >(); }
77     /** Aligns the stream according to the passed type and skips the size of the type. */
78     template< typename Type >
skipAligned()79     inline void         skipAligned() { align( sizeof( Type ) ); skip( sizeof( Type ) ); }
80 
81 private:
82     BinaryInputStream*  mpInStrm;           /// The wrapped input stream.
83     sal_Int64           mnStrmPos;          /// Tracks relative position in the stream.
84     sal_Int64           mnStrmSize;         /// Size of the wrapped stream data.
85 };
86 
87 // ============================================================================
88 
89 /** A pair of integer values as a property. */
90 typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData;
91 
92 /** An array of string values as a property. */
93 typedef ::std::vector< ::rtl::OUString > AxStringArray;
94 
95 // ============================================================================
96 
97 const sal_Char* const AX_GUID_CFONT         = "{AFC20920-DA4E-11CE-B943-00AA006887B4}";
98 
99 const sal_uInt32 AX_FONTDATA_BOLD           = 0x00000001;
100 const sal_uInt32 AX_FONTDATA_ITALIC         = 0x00000002;
101 const sal_uInt32 AX_FONTDATA_UNDERLINE      = 0x00000004;
102 const sal_uInt32 AX_FONTDATA_STRIKEOUT      = 0x00000008;
103 const sal_uInt32 AX_FONTDATA_DISABLED       = 0x00002000;
104 const sal_uInt32 AX_FONTDATA_AUTOCOLOR      = 0x40000000;
105 
106 const sal_Int32 AX_FONTDATA_LEFT            = 1;
107 const sal_Int32 AX_FONTDATA_RIGHT           = 2;
108 const sal_Int32 AX_FONTDATA_CENTER          = 3;
109 
110 /** All entries of a font property. */
111 struct AxFontData
112 {
113     ::rtl::OUString     maFontName;         /// Name of the used font.
114     sal_uInt32          mnFontEffects;      /// Font effect flags.
115     sal_Int32           mnFontHeight;       /// Height of the font (not really twips, see code).
116     sal_Int32           mnFontCharSet;      /// Windows character set of the font.
117     sal_Int32           mnHorAlign;         /// Horizontal text alignment.
118     bool                mbDblUnderline;     /// True = double underline style (legacy VML drawing controls only).
119 
120     explicit            AxFontData();
121 
122     /** Converts the internal representation of the font height to points. */
123     sal_Int16           getHeightPoints() const;
124     /** Converts the passed font height from points to the internal representation. */
125     void                setHeightPoints( sal_Int16 nPoints );
126 
127     /** Reads the font data settings from the passed input stream. */
128     bool                importBinaryModel( BinaryInputStream& rInStrm );
129     /** Reads the font data settings from the passed input stream that contains
130         an OLE StdFont structure. */
131     bool                importStdFont( BinaryInputStream& rInStrm );
132     /** Reads the font data settings from the passed input stream depending on
133         the GUID preceding the actual font data. */
134     bool                importGuidAndFont( BinaryInputStream& rInStrm );
135 };
136 
137 // ============================================================================
138 
139 /** Import helper to read simple and complex ActiveX form control properties
140     from a binary input stream. */
141 class AxBinaryPropertyReader
142 {
143 public:
144     explicit            AxBinaryPropertyReader( BinaryInputStream& rInStrm, bool b64BitPropFlags = false );
145 
146     /** Reads the next integer property value from the stream, if the
147         respective flag in the property mask is set. */
148     template< typename StreamType, typename DataType >
readIntProperty(DataType & ornValue)149     inline void         readIntProperty( DataType& ornValue )
150                             { if( startNextProperty() ) ornValue = maInStrm.readAligned< StreamType >(); }
151     /** Reads the next boolean property value from the stream, if the
152         respective flag in the property mask is set. */
153     void                readBoolProperty( bool& orbValue, bool bReverse = false );
154     /** Reads the next pair property from the stream, if the respective flag in
155         the property mask is set. */
156     void                readPairProperty( AxPairData& orPairData );
157     /** Reads the next string property from the stream, if the respective flag
158         in the property mask is set. */
159     void                readStringProperty( ::rtl::OUString& orValue );
160     /** Reads a string array property from the stream, if the respective flag
161         in the property mask is set. */
162     void                readStringArrayProperty( AxStringArray& orArray );
163     /** Reads the next GUID property from the stream, if the respective flag
164         in the property mask is set. The GUID will be enclosed in braces. */
165     void                readGuidProperty( ::rtl::OUString& orGuid );
166     /** Reads the next font property from the stream, if the respective flag in
167         the property mask is set. */
168     void                readFontProperty( AxFontData& orFontData );
169     /** Reads the next picture property from the stream, if the respective flag
170         in the property mask is set. */
171     void                readPictureProperty( StreamDataSequence& orPicData );
172 
173     /** Skips the next integer property value in the stream, if the respective
174         flag in the property mask is set. */
175     template< typename StreamType >
skipIntProperty()176     inline void         skipIntProperty() { if( startNextProperty() ) maInStrm.skipAligned< StreamType >(); }
177     /** Skips the next boolean property value in the stream, if the respective
178         flag in the property mask is set. */
skipBoolProperty()179     inline void         skipBoolProperty() { startNextProperty(); }
180     /** Skips the next pair property in the stream, if the respective flag in
181         the property mask is set. */
skipPairProperty()182     void                skipPairProperty() { readPairProperty( maDummyPairData ); }
183     /** Skips the next string property in the stream, if the respective flag in
184         the property mask is set. */
skipStringProperty()185     inline void         skipStringProperty() { readStringProperty( maDummyString ); }
186     /** Skips the next string array property in the stream, if the respective
187         flag in the property mask is set. */
skipStringArrayProperty()188     inline void         skipStringArrayProperty() { readStringArrayProperty( maDummyStringArray ); }
189     /** Skips the next GUID property in the stream, if the respective flag in
190         the property mask is set. */
skipGuidProperty()191     inline void         skipGuidProperty() { readGuidProperty( maDummyString ); }
192     /** Skips the next font property in the stream, if the respective flag in
193         the property mask is set. */
skipFontProperty()194     inline void         skipFontProperty() { readFontProperty( maDummyFontData ); }
195     /** Skips the next picture property in the stream, if the respective flag
196         in the property mask is set. */
skipPictureProperty()197     inline void         skipPictureProperty() { readPictureProperty( maDummyPicData ); }
198     /** Has to be called for undefined properties. If the respective flag in
199         the mask is set, the property import cannot be finished successfully. */
skipUndefinedProperty()200     inline void         skipUndefinedProperty() { ensureValid( !startNextProperty() ); }
201 
202     /** Final processing, reads contents of all complex properties. */
203     bool                finalizeImport();
204 
205 private:
206     bool                ensureValid( bool bCondition = true );
207     bool                startNextProperty();
208 
209 private:
210     /** Base class for complex properties such as string, point, size, GUID, picture. */
211     struct ComplexProperty
212     {
213         virtual             ~ComplexProperty();
214         virtual bool        readProperty( AxAlignedInputStream& rInStrm ) = 0;
215     };
216 
217     /** Complex property for a 32-bit value pair, e.g. point or size. */
218     struct PairProperty : public ComplexProperty
219     {
220         AxPairData&         mrPairData;
221 
PairPropertyoox::ole::AxBinaryPropertyReader::PairProperty222         inline explicit     PairProperty( AxPairData& rPairData ) :
223                                 mrPairData( rPairData ) {}
224         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
225     };
226 
227     /** Complex property for a string value. */
228     struct StringProperty : public ComplexProperty
229     {
230         ::rtl::OUString&    mrValue;
231         sal_uInt32          mnSize;
232 
StringPropertyoox::ole::AxBinaryPropertyReader::StringProperty233         inline explicit     StringProperty( ::rtl::OUString& rValue, sal_uInt32 nSize ) :
234                                 mrValue( rValue ), mnSize( nSize ) {}
235         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
236     };
237 
238     /** Complex property for an array of strings. */
239     struct StringArrayProperty : public ComplexProperty
240     {
241         AxStringArray&      mrArray;
242         sal_uInt32          mnSize;
StringArrayPropertyoox::ole::AxBinaryPropertyReader::StringArrayProperty243         inline explicit     StringArrayProperty( AxStringArray& rArray, sal_uInt32 nSize ) :
244                                 mrArray( rArray ), mnSize( nSize ) {}
245         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
246     };
247 
248     /** Complex property for a GUID value. */
249     struct GuidProperty : public ComplexProperty
250     {
251         ::rtl::OUString&    mrGuid;
252 
GuidPropertyoox::ole::AxBinaryPropertyReader::GuidProperty253         inline explicit     GuidProperty( ::rtl::OUString& rGuid ) :
254                                 mrGuid( rGuid ) {}
255         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
256     };
257 
258     /** Stream property for a font structure. */
259     struct FontProperty : public ComplexProperty
260     {
261         AxFontData&         mrFontData;
262 
FontPropertyoox::ole::AxBinaryPropertyReader::FontProperty263         inline explicit     FontProperty( AxFontData& rFontData ) :
264                                 mrFontData( rFontData ) {}
265         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
266     };
267 
268     /** Stream property for a picture or mouse icon. */
269     struct PictureProperty : public ComplexProperty
270     {
271         StreamDataSequence& mrPicData;
272 
PicturePropertyoox::ole::AxBinaryPropertyReader::PictureProperty273         inline explicit     PictureProperty( StreamDataSequence& rPicData ) :
274                                 mrPicData( rPicData ) {}
275         virtual bool        readProperty( AxAlignedInputStream& rInStrm );
276     };
277 
278     typedef RefVector< ComplexProperty > ComplexPropVector;
279 
280 private:
281     AxAlignedInputStream maInStrm;          /// The input stream to read from.
282     ComplexPropVector   maLargeProps;       /// Stores info for all used large properties.
283     ComplexPropVector   maStreamProps;      /// Stores info for all used stream data properties.
284     AxPairData          maDummyPairData;    /// Dummy pair for unsupported properties.
285     AxFontData          maDummyFontData;    /// Dummy font for unsupported properties.
286     StreamDataSequence  maDummyPicData;     /// Dummy picture for unsupported properties.
287     ::rtl::OUString     maDummyString;      /// Dummy string for unsupported properties.
288     AxStringArray       maDummyStringArray; /// Dummy string array for unsupported properties.
289     sal_Int64           mnPropFlags;        /// Flags specifying existing properties.
290     sal_Int64           mnNextProp;         /// Next property to read.
291     sal_Int64           mnPropsEnd;         /// End position of simple/large properties.
292     bool                mbValid;            /// True = stream still valid.
293 };
294 
295 // ============================================================================
296 
297 } // namespace ole
298 } // namespace oox
299 
300 #endif
301