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