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 // ============================================================================ 25 26 #ifndef SC_XESTREAM_HXX 27 #define SC_XESTREAM_HXX 28 29 #include <com/sun/star/beans/NamedValue.hpp> 30 31 #include <map> 32 #include <stack> 33 #include <string> 34 35 #include <oox/core/xmlfilterbase.hxx> 36 #include <oox/token/tokens.hxx> 37 #include <sax/fshelper.hxx> 38 39 #include "xlstream.hxx" 40 #include "xestring.hxx" 41 42 #include <filter/msfilter/mscodec.hxx> 43 #include <vector> 44 45 /* ============================================================================ 46 Output stream class for Excel export 47 - CONTINUE record handling 48 - ByteString and UniString support 49 ============================================================================ */ 50 51 class XclExpRoot; 52 class XclExpBiff8Encrypter; 53 typedef ScfRef< XclExpBiff8Encrypter > XclExpEncrypterRef; 54 55 /** This class is used to export Excel record streams. 56 @descr An instance is constructed with an SvStream and the maximum size of Excel 57 record contents (in BIFF5: 2080 bytes, in BIFF8: 8224 bytes). 58 59 To start writing a record call StartRecord(). Parameters are the record identifier 60 and any calculated record size. This is for optimizing the write process: if the real 61 written data has the same size as the calculated, the stream will not seek back and 62 update the record size field. But it is not mandatory to calculate a size. Each 63 record must be closed by calling EndRecord(). This will check (and update) the record 64 size field. 65 66 If some data exceeds the record size limit, a CONTINUE record is started automatically 67 and the new data will be written to this record. 68 69 If specific data pieces must not be splitted, use SetSliceLen(). For instance: 70 To write a sequence of 16-bit values, where 4 values form a unit and cannot be 71 split, call SetSliceLen( 8 ) first (4*2 bytes == 8). 72 73 To write unicode character arrays, call WriteUnicodeBuffer(). It creates CONTINUE 74 records and repeats the unicode string flag byte automatically. This function is used 75 for instance from the class XclExpString which can write complete unicode strings. 76 */ 77 class XclExpStream 78 { 79 public: 80 /** Constructs the Excel record export stream. 81 @param rOutStrm The system output stream to write to. 82 @param nMaxRecSize The maximum allowed size of record content (depending on BIFF type). 83 If 0 is passed, the record size will be set automatically, depending on the current BIFF type. */ 84 XclExpStream( 85 SvStream& rOutStrm, 86 const XclExpRoot& rRoot, 87 sal_uInt16 nMaxRecSize = 0 ); 88 89 ~XclExpStream(); 90 91 /** Returns the filter root data. */ GetRoot() const92 inline const XclExpRoot& GetRoot() const { return mrRoot; } 93 94 /** Starts a new record: writes header data, stores calculated record size. */ 95 void StartRecord( sal_uInt16 nRecId, sal_Size nRecSize ); 96 /** Checks and corrects real record length. Must be called everytime a record is finished. */ 97 void EndRecord(); 98 99 /** Returns the position inside of current record (starts by 0 in every CONTINUE). */ GetRawRecPos() const100 inline sal_uInt16 GetRawRecPos() const { return mnCurrSize; } 101 102 /** Returns the maximum size of a record. */ GetMaxRecSize() const103 inline sal_uInt16 GetMaxRecSize() const { return mnMaxRecSize; } 104 /** Sets maximum record size (valid only for current record). */ SetMaxRecSize(sal_uInt16 nMax)105 inline void SetMaxRecSize( sal_uInt16 nMax ) { mnCurrMaxSize = nMax; } 106 /** Sets maximum size of CONTINUE records (valid only for current record). */ SetMaxContSize(sal_uInt16 nMax)107 inline void SetMaxContSize( sal_uInt16 nMax ) { mnMaxContSize = nMax; } 108 109 /** Sets data slice length. 0 = no slices. */ 110 void SetSliceSize( sal_uInt16 nSize ); 111 112 XclExpStream& operator<<( sal_Int8 nValue ); 113 XclExpStream& operator<<( sal_uInt8 nValue ); 114 XclExpStream& operator<<( sal_Int16 nValue ); 115 XclExpStream& operator<<( sal_uInt16 nValue ); 116 XclExpStream& operator<<( sal_Int32 nValue ); 117 XclExpStream& operator<<( sal_uInt32 nValue ); 118 XclExpStream& operator<<( float fValue ); 119 XclExpStream& operator<<( double fValue ); 120 121 /** Writes nBytes bytes from memory. */ 122 sal_Size Write( const void* pData, sal_Size nBytes ); 123 /** Writes a sequence of nBytes zero bytes (respects slice setting). */ 124 void WriteZeroBytes( sal_Size nBytes ); 125 126 void WriteZeroBytesToRecord( sal_Size nBytes ); 127 128 /** Copies nBytes bytes from current position of the stream rInStrm. 129 @descr Omitting the second parameter means: read to end of stream. */ 130 sal_Size CopyFromStream( SvStream& rInStrm, sal_Size nBytes = STREAM_SEEK_TO_END ); 131 132 // *** unicode string export is realized with helper class XclExpString *** 133 // (slice length setting has no effect here -> disabled automatically) 134 135 //UNUSED2008-05 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */ 136 //UNUSED2008-05 void WriteUnicodeBuffer( const sal_uInt16* pBuffer, sal_Size nChars, sal_uInt8 nFlags ); 137 138 /** Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record. */ 139 void WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags ); 140 141 // *** write 8-bit-strings *** 142 // (slice length setting has no effect here -> disabled automatically) 143 144 //UNUSED2008-05 /** Writes ByteString buffer (without string length field). */ 145 //UNUSED2008-05 void WriteByteStringBuffer( 146 //UNUSED2008-05 const ByteString& rString, 147 //UNUSED2008-05 sal_uInt16 nMaxLen = 0x00FF ); 148 149 /** Writes string length field and ByteString buffer. */ 150 void WriteByteString( 151 const ByteString& rString, 152 sal_uInt16 nMaxLen = 0x00FF, 153 bool b16BitCount = false ); 154 155 /** Writes 8-bit character buffer. */ 156 void WriteCharBuffer( const ScfUInt8Vec& rBuffer ); 157 158 // *** SvStream access *** 159 160 /** Sets position of system stream (only allowed outside of records). */ 161 sal_Size SetSvStreamPos( sal_Size nPos ); 162 /** Returns the absolute position of the system stream. */ GetSvStreamPos() const163 inline sal_Size GetSvStreamPos() const { return mrStrm.Tell(); } 164 165 void SetEncrypter( XclExpEncrypterRef xEncrypter ); 166 167 bool HasValidEncrypter() const; 168 169 void EnableEncryption( bool bEnable = true ); 170 171 void DisableEncryption(); 172 173 private: 174 /** Writes header data, internal setup. */ 175 void InitRecord( sal_uInt16 nRecId ); 176 /** Rewrites correct record length, if different from calculated. */ 177 void UpdateRecSize(); 178 /** Recalculates mnCurrSize and mnSliceSize. */ 179 void UpdateSizeVars( sal_Size nSize ); 180 /** Writes CONTINUE header, internal setup. */ 181 void StartContinue(); 182 /** Refreshes counter vars, creates CONTINUE records. */ 183 void PrepareWrite( sal_uInt16 nSize ); 184 /** Creates CONTINUE record at end of record. 185 @return Maximum data block size remaining. */ 186 sal_uInt16 PrepareWrite(); 187 188 /** Writes a raw sequence of zero bytes. */ 189 void WriteRawZeroBytes( sal_Size nBytes ); 190 191 private: 192 SvStream& mrStrm; /// Reference to the system output stream. 193 const XclExpRoot& mrRoot; /// Filter root data. 194 195 bool mbUseEncrypter; 196 XclExpEncrypterRef mxEncrypter; 197 198 // length data 199 sal_uInt16 mnMaxRecSize; /// Maximum size of record content. 200 sal_uInt16 mnMaxContSize; /// Maximum size of CONTINUE content. 201 sal_uInt16 mnCurrMaxSize; /// Current maximum, either mnMaxRecSize or mnMaxContSize. 202 sal_uInt16 mnMaxSliceSize; /// Maximum size of data slices (parts that cannot be split). 203 sal_uInt16 mnHeaderSize; /// Record size written in last record header. 204 sal_uInt16 mnCurrSize; /// Count of bytes already written in current record. 205 sal_uInt16 mnSliceSize; /// Count of bytes already written in current slice. 206 sal_Size mnPredictSize; /// Predicted size received from calling function. 207 208 // stream position data 209 sal_Size mnLastSizePos; /// Stream position of size field in current header. 210 bool mbInRec; /// true = currently writing inside of a record. 211 }; 212 213 // ============================================================================ 214 215 class XclExpBiff8Encrypter 216 { 217 public: 218 explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot ); 219 ~XclExpBiff8Encrypter(); 220 221 bool IsValid() const; 222 223 void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const; 224 void GetSalt( sal_uInt8 pnSalt[16] ) const; 225 void GetDocId( sal_uInt8 pnDocId[16] ) const; 226 227 void Encrypt( SvStream& rStrm, sal_uInt8 nData ); 228 void Encrypt( SvStream& rStrm, sal_uInt16 nData ); 229 void Encrypt( SvStream& rStrm, sal_uInt32 nData ); 230 231 void Encrypt( SvStream& rStrm, sal_Int8 nData ); 232 void Encrypt( SvStream& rStrm, sal_Int16 nData ); 233 void Encrypt( SvStream& rStrm, sal_Int32 nData ); 234 235 void Encrypt( SvStream& rStrm, float fValue ); 236 void Encrypt( SvStream& rStrm, double fValue ); 237 238 void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes ); 239 240 private: 241 void Init( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& aEncryptionData ); 242 243 sal_uInt32 GetBlockPos( sal_Size nStrmPos ) const; 244 sal_uInt16 GetOffsetInBlock( sal_Size nStrmPos ) const; 245 246 private: 247 ::msfilter::MSCodec_Std97 maCodec; /// Crypto algorithm implementation. 248 sal_uInt8 mpnDocId[16]; 249 sal_uInt8 mpnSalt[16]; 250 sal_uInt8 mpnSaltDigest[16]; 251 252 const XclExpRoot& mrRoot; 253 sal_Size mnOldPos; /// Last known stream position 254 bool mbValid; 255 }; 256 257 // ---------------------------------------------------------------------------- 258 259 260 // ============================================================================ 261 262 // `s.GetChar(0) != 0` needed because some strings on export only contain NULL. 263 #define XESTRING_TO_PSZ(s) \ 264 (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : NULL) 265 266 class ScAddress; 267 class ScDocument; 268 class ScRange; 269 class ScRangeList; 270 class ScTokenArray; 271 struct XclAddress; 272 struct XclFontData; 273 class XclRangeList; 274 275 class XclXmlUtils 276 { 277 XclXmlUtils(); 278 ~XclXmlUtils(); 279 XclXmlUtils(const XclXmlUtils&); 280 XclXmlUtils& operator=(const XclXmlUtils&); 281 public: 282 static ::rtl::OUString GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId ); 283 284 static ::rtl::OString ToOString( const Color& rColor ); 285 static ::rtl::OString ToOString( const ::rtl::OUString& s ); 286 static ::rtl::OString ToOString( const ScfUInt16Vec& rBuffer ); 287 static ::rtl::OString ToOString( const String& s ); 288 static ::rtl::OString ToOString( const ScAddress& rRange ); 289 static ::rtl::OString ToOString( const ScRange& rRange ); 290 static ::rtl::OString ToOString( const ScRangeList& rRangeList ); 291 static ::rtl::OString ToOString( const XclAddress& rAddress ); 292 static ::rtl::OString ToOString( const XclExpString& s ); 293 static ::rtl::OString ToOString( const XclRangeList& rRangeList ); 294 295 static ::rtl::OUString ToOUString( const char* s ); 296 static ::rtl::OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 ); 297 static ::rtl::OUString ToOUString( const String& s ); 298 static ::rtl::OUString ToOUString( ScDocument& rDocument, const ScAddress& rAddress, ScTokenArray* pTokenArray ); 299 static ::rtl::OUString ToOUString( const XclExpString& s ); 300 static const char* ToPsz( bool b ); 301 }; 302 303 class XclExpXmlStream : public oox::core::XmlFilterBase 304 { 305 public: 306 XclExpXmlStream( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rxContext, SvStream& rStrm, const XclExpRoot& rRoot ); 307 virtual ~XclExpXmlStream(); 308 309 /** Returns the filter root data. */ GetRoot() const310 inline const XclExpRoot& GetRoot() const { return mrRoot; } 311 312 sax_fastparser::FSHelperPtr& GetCurrentStream(); 313 void PushStream( sax_fastparser::FSHelperPtr aStream ); 314 void PopStream(); 315 316 ::rtl::OUString GetIdForPath( const ::rtl::OUString& rPath ); 317 sax_fastparser::FSHelperPtr GetStreamForPath( const ::rtl::OUString& rPath ); 318 319 sax_fastparser::FSHelperPtr& WriteAttributes( sal_Int32 nAttribute, ... ); 320 sax_fastparser::FSHelperPtr& WriteFontData( const XclFontData& rFontData, sal_Int32 nNameId ); 321 322 sax_fastparser::FSHelperPtr CreateOutputStream ( 323 const ::rtl::OUString& sFullStream, 324 const ::rtl::OUString& sRelativeStream, 325 const ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >& xParentRelation, 326 const char* sContentType, 327 const char* sRelationshipType, 328 ::rtl::OUString* pRelationshipId = NULL ); 329 330 // ignore 331 virtual bool exportDocument() throw(); 332 333 // only needed for import; ignore 334 virtual bool importDocument() throw(); 335 virtual oox::vml::Drawing* getVmlDrawing(); 336 virtual const oox::drawingml::Theme* getCurrentTheme() const; 337 virtual const oox::drawingml::table::TableStyleListPtr getTableStyles(); 338 virtual oox::drawingml::chart::ChartConverter& getChartConverter(); 339 340 void Trace( const char* format, ...); 341 private: 342 virtual ::oox::ole::VbaProject* implCreateVbaProject() const; 343 virtual ::rtl::OUString implGetImplementationName() const; 344 345 typedef std::map< ::rtl::OUString, 346 std::pair< ::rtl::OUString, 347 sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap; 348 349 const XclExpRoot& mrRoot; /// Filter root data. 350 std::stack< sax_fastparser::FSHelperPtr > maStreams; 351 XclExpXmlPathToStateMap maOpenedStreamMap; 352 }; 353 354 #endif 355 356