LibreOffice Module sc (master)  1
xestream.hxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #pragma once
21 
22 #include <map>
23 #include <stack>
24 #include <string_view>
25 
26 #include <rtl/strbuf.hxx>
27 
29 #include <sax/fshelper.hxx>
30 #include <tools/stream.hxx>
31 #include <formula/errorcodes.hxx>
32 #include "ftools.hxx"
33 #include <types.hxx>
34 
36 #include <vector>
37 
38 namespace com::sun::star::beans { struct NamedValue; }
39 
40 /* ============================================================================
41 Output stream class for Excel export
42 - CONTINUE record handling
43 ============================================================================ */
44 
45 class XclExpString;
46 class XclExpRoot;
48 typedef std::shared_ptr< XclExpBiff8Encrypter > XclExpEncrypterRef;
49 
73 {
74 public:
80  SvStream& rOutStrm,
81  const XclExpRoot& rRoot,
82  sal_uInt16 nMaxRecSize = 0 );
83 
84  ~XclExpStream();
85 
87  const XclExpRoot& GetRoot() const { return mrRoot; }
88 
90  void StartRecord( sal_uInt16 nRecId, std::size_t nRecSize );
92  void EndRecord();
93 
95  sal_uInt16 GetRawRecPos() const { return mnCurrSize; }
96 
98  void SetSliceSize( sal_uInt16 nSize );
99 
100  XclExpStream& operator<<( sal_Int8 nValue );
101  XclExpStream& operator<<( sal_uInt8 nValue );
102  XclExpStream& operator<<( sal_Int16 nValue );
103  XclExpStream& operator<<( sal_uInt16 nValue );
104  XclExpStream& operator<<( sal_Int32 nValue );
105  XclExpStream& operator<<( sal_uInt32 nValue );
106  XclExpStream& operator<<( float fValue );
107  XclExpStream& operator<<( double fValue );
108 
110  std::size_t Write( const void* pData, std::size_t nBytes );
112  void WriteZeroBytes( std::size_t nBytes );
113 
114  void WriteZeroBytesToRecord( std::size_t nBytes );
115 
118  void CopyFromStream( SvStream& rInStrm, sal_uInt64 nBytes = STREAM_SEEK_TO_END );
119 
120  // *** unicode string export is realized with helper class XclExpString ***
121  // (slice length setting has no effect here -> disabled automatically)
122 
124  void WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags );
125 
126  // *** write 8-bit-strings ***
127  // (slice length setting has no effect here -> disabled automatically)
128 
130  void WriteByteString( const OString& rString );
131 
133  void WriteCharBuffer( const ScfUInt8Vec& rBuffer );
134 
135  // *** SvStream access ***
136 
138  void SetSvStreamPos(sal_uInt64 nPos);
140  sal_uInt64 GetSvStreamPos() const { return mrStrm.Tell(); }
141 
142  void SetEncrypter( XclExpEncrypterRef const & xEncrypter );
143 
144  bool HasValidEncrypter() const;
145 
146  void EnableEncryption( bool bEnable = true );
147 
148  void DisableEncryption();
149 
150 private:
152  void InitRecord( sal_uInt16 nRecId );
154  void UpdateRecSize();
156  void UpdateSizeVars( std::size_t nSize );
158  void StartContinue();
160  void PrepareWrite( sal_uInt16 nSize );
163  sal_uInt16 PrepareWrite();
164 
166  void WriteRawZeroBytes( std::size_t nBytes );
167 
168 private:
171 
174 
175  // length data
176  sal_uInt16 mnMaxRecSize;
177  sal_uInt16 mnMaxContSize;
178  sal_uInt16 mnCurrMaxSize;
179  sal_uInt16 mnMaxSliceSize;
180  sal_uInt16 mnHeaderSize;
181  sal_uInt16 mnCurrSize;
182  sal_uInt16 mnSliceSize;
183  std::size_t mnPredictSize;
184 
185  // stream position data
186  std::size_t mnLastSizePos;
187  bool mbInRec;
188 };
189 
191 {
192 public:
193  explicit XclExpBiff8Encrypter( const XclExpRoot& rRoot );
195 
196  bool IsValid() const { return mbValid; }
197 
198  void GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const;
199  void GetSalt( sal_uInt8 pnSalt[16] ) const;
200  void GetDocId( sal_uInt8 pnDocId[16] ) const;
201 
202  void Encrypt( SvStream& rStrm, sal_uInt8 nData );
203  void Encrypt( SvStream& rStrm, sal_uInt16 nData );
204  void Encrypt( SvStream& rStrm, sal_uInt32 nData );
205 
206  void Encrypt( SvStream& rStrm, sal_Int8 nData );
207  void Encrypt( SvStream& rStrm, sal_Int16 nData );
208  void Encrypt( SvStream& rStrm, sal_Int32 nData );
209 
210  void Encrypt( SvStream& rStrm, float fValue );
211  void Encrypt( SvStream& rStrm, double fValue );
212 
213  void EncryptBytes( SvStream& rStrm, ::std::vector<sal_uInt8>& aBytes );
214 
215 private:
216  void Init( const css::uno::Sequence< css::beans::NamedValue >& aEncryptionData );
217 
218  static sal_uInt32 GetBlockPos( std::size_t nStrmPos );
219  static sal_uInt16 GetOffsetInBlock( std::size_t nStrmPos );
220 
221 private:
226 
227  sal_uInt64 mnOldPos;
228  bool mbValid;
229 };
230 
231 // `s.GetChar(0) != 0` needed because some strings on export only contain NULL.
232 #define XESTRING_TO_PSZ(s) \
233  (s.Len() && s.GetChar( 0 ) != 0 ? XclXmlUtils::ToOString( s ).getStr() : nullptr)
234 
235 class ScAddress;
236 class ScDocShell;
237 class ScFormulaCell;
238 class ScRange;
239 class ScRangeList;
240 class ScTokenArray;
241 struct XclAddress;
242 struct XclFontData;
243 class XclRangeList;
244 namespace sc { class CompileFormulaContext; }
245 
247 {
248 public:
249  XclXmlUtils() = delete;
250  ~XclXmlUtils() = delete;
251  XclXmlUtils(const XclXmlUtils&) = delete;
252  XclXmlUtils& operator=(const XclXmlUtils&) = delete;
253 
254  static void GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& sType, OUString& rValue);
255  static OUString GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId );
256 
257  static OString ToOString( const Color& rColor );
258  static OString ToOString( const ScfUInt16Vec& rBuffer );
259  static OStringBuffer& ToOString( OStringBuffer& s, const ScAddress& rRange );
260  static OString ToOString( const ScDocument& rDoc, const ScRange& rRange, bool bFullAddressNotation = false );
261  static OString ToOString( const ScDocument& rDoc, const ScRangeList& rRangeList );
262  static OStringBuffer& ToOString( OStringBuffer& s, const XclAddress& rAddress );
263  static OString ToOString( const XclExpString& s );
264  static OString ToOString( const ScDocument& rDoc, const XclRangeList& rRangeList );
265 
266  static OUString ToOUString( const char* s );
267  static OUString ToOUString( const ScfUInt16Vec& rBuffer, sal_Int32 nStart = 0, sal_Int32 nLength = -1 );
268  static OUString ToOUString( sc::CompileFormulaContext& rCtx, const ScAddress& rAddress,
269  const ScTokenArray* pTokenArray, FormulaError nErrCode = FormulaError::NONE );
270  static OUString ToOUString( const XclExpString& s );
271 
272  template <class T>
273  static sax_fastparser::FSHelperPtr WriteElement(sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const T& value)
274  {
275  pStream->startElement(nElement);
276  pStream->write(value);
277  pStream->endElement(nElement);
278 
279  return pStream;
280  }
281  static sax_fastparser::FSHelperPtr WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nNameId );
282 };
283 
285 {
286 public:
287  XclExpXmlStream( const css::uno::Reference< css::uno::XComponentContext >& rCC, bool bExportVBA, bool bExportTemplate );
288  virtual ~XclExpXmlStream() override;
289 
291  const XclExpRoot& GetRoot() const { return *mpRoot; }
292 
294  void PushStream( sax_fastparser::FSHelperPtr const & aStream );
295  void PopStream();
296 
297  sax_fastparser::FSHelperPtr GetStreamForPath( const OUString& rPath );
298 
299  template <typename Str, typename... Args>
300  void WriteAttributes(sal_Int32 nAttribute, Str&& value, Args&&... rest)
301  {
302  WriteAttribute(nAttribute, std::forward<Str>(value));
303  if constexpr(sizeof...(rest) > 0)
304  {
305  // coverity[stray_semicolon : FALSE] - coverity parse error
306  WriteAttributes(std::forward<Args>(rest)...);
307  }
308  }
309 
311  const OUString& sFullStream,
312  const OUString& sRelativeStream,
313  const css::uno::Reference< css::io::XOutputStream >& xParentRelation,
314  const char* sContentType,
315  std::u16string_view sRelationshipType,
316  OUString* pRelationshipId = nullptr );
317 
318  // ignore
319  virtual bool exportDocument() override;
320 
321  // only needed for import; ignore
322  virtual bool importDocument() throw() override;
323  virtual oox::vml::Drawing* getVmlDrawing() override;
324  virtual const oox::drawingml::Theme* getCurrentTheme() const override;
325  virtual oox::drawingml::table::TableStyleListPtr getTableStyles() override;
326  virtual oox::drawingml::chart::ChartConverter* getChartConverter() override;
327 
328 private:
329  virtual ::oox::ole::VbaProject* implCreateVbaProject() const override;
330  virtual OUString SAL_CALL getImplementationName() override;
332  void WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal);
333  void WriteAttribute(sal_Int32 nAttr, std::string_view sVal)
334  {
335  WriteAttribute(nAttr, OStringToOUString(sVal, RTL_TEXTENCODING_UTF8));
336  }
337  void WriteAttribute(sal_Int32 nAttr, const char* sVal)
338  {
339  if (sVal)
340  WriteAttribute(nAttr, OUString(sVal, strlen(sVal), RTL_TEXTENCODING_UTF8));
341  }
342 
343  void validateTabNames(std::vector<OUString>& aOriginalTabNames);
344  void restoreTabNames(const std::vector<OUString>& aOriginalTabNames);
345  void renameTab(SCTAB aTab, OUString aNewName);
346 
347  typedef std::map< OUString,
348  std::pair< OUString,
350 
352  std::stack< sax_fastparser::FSHelperPtr > maStreams;
353  XclExpXmlPathToStateMap maOpenedStreamMap;
354 
357 };
358 
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual const oox::drawingml::Theme * getCurrentTheme() const override
Definition: xestream.cxx:974
void WriteAttributes(sal_Int32 nAttribute, Str &&value, Args &&...rest)
Definition: xestream.hxx:300
This class stores an unformatted or formatted string for Excel export.
Definition: xestring.hxx:47
void GetSaltDigest(sal_uInt8 pnSaltDigest[16]) const
Definition: xestream.cxx:473
virtual oox::vml::Drawing * getVmlDrawing() override
Definition: xestream.cxx:969
void StartContinue()
Writes CONTINUE header, internal setup.
Definition: xestream.cxx:411
::std::vector< sal_uInt8 > ScfUInt8Vec
Definition: ftools.hxx:253
std::size_t Write(const void *pData, std::size_t nBytes)
Writes nBytes bytes from memory.
Definition: xestream.cxx:216
static void GetFormulaTypeAndValue(ScFormulaCell &rCell, const char *&sType, OUString &rValue)
Definition: xestream.cxx:658
static OString ToOString(const Color &rColor)
Definition: xestream.cxx:699
sal_uInt16 mnCurrSize
Record size written in last record header.
Definition: xestream.hxx:181
void SetEncrypter(XclExpEncrypterRef const &xEncrypter)
Definition: xestream.cxx:349
const XclExpRoot & GetRoot() const
Returns the filter root data.
Definition: xestream.hxx:291
static sax_fastparser::FSHelperPtr WriteElement(sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const T &value)
Definition: xestream.hxx:273
This class is used to export Excel record streams.
Definition: xestream.hxx:72
sal_uInt16 GetRawRecPos() const
Returns the position inside of current record (starts by 0 in every CONTINUE).
Definition: xestream.hxx:95
signed char sal_Int8
sal_uInt16 mnMaxContSize
Maximum size of record content.
Definition: xestream.hxx:177
static OUString ToOUString(const char *s)
Definition: xestream.cxx:784
virtual OUString SAL_CALL getImplementationName() override
Definition: xestream.cxx:1134
std::shared_ptr< TableStyleList > TableStyleListPtr
sal_uInt16 mnCurrMaxSize
Maximum size of CONTINUE content.
Definition: xestream.hxx:178
virtual bool exportDocument() override
Definition: xestream.cxx:1002
bool mbInRec
Stream position of size field in current header.
Definition: xestream.hxx:187
This struct helps reading and writing Excel fonts.
Definition: xlstyle.hxx:285
bool HasValidEncrypter() const
Definition: xestream.cxx:354
sal_Int16 nId
std::shared_ptr< XclExpBiff8Encrypter > XclExpEncrypterRef
Definition: xestream.hxx:47
void EncryptBytes(SvStream &rStrm,::std::vector< sal_uInt8 > &aBytes)
Definition: xestream.cxx:580
::msfilter::MSCodec_Std97 maCodec
Definition: xestream.hxx:222
sal_uInt16 mnMaxSliceSize
Current maximum, either mnMaxRecSize or mnMaxContSize.
Definition: xestream.hxx:179
XclExpXmlStream(const css::uno::Reference< css::uno::XComponentContext > &rCC, bool bExportVBA, bool bExportTemplate)
Definition: xestream.cxx:898
sal_uInt16 mnSliceSize
Count of bytes already written in current record.
Definition: xestream.hxx:182
virtual ~XclExpXmlStream() override
Definition: xestream.cxx:906
void Encrypt(SvStream &rStrm, sal_uInt8 nData)
Definition: xestream.cxx:491
sax_fastparser::FSHelperPtr GetStreamForPath(const OUString &rPath)
Definition: xestream.cxx:928
css::uno::Any const & rValue
const XclExpRoot * mpRoot
Definition: xestream.hxx:351
Access to global data from other classes.
Definition: xeroot.hxx:112
virtual bool importDocument() override
Definition: xestream.cxx:964
SvStream & mrStrm
Definition: xestream.hxx:169
~XclXmlUtils()=delete
void PushStream(sax_fastparser::FSHelperPtr const &aStream)
Definition: xestream.cxx:917
static sax_fastparser::FSHelperPtr WriteFontData(sax_fastparser::FSHelperPtr pStream, const XclFontData &rFontData, sal_Int32 nNameId)
Definition: xestream.cxx:867
void WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal)
Definition: xestream.cxx:935
void validateTabNames(std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1139
ScDocShell * getDocShell()
Definition: xestream.cxx:990
const XclExpRoot & mrRoot
Reference to the system output stream.
Definition: xestream.hxx:170
sal_uInt16 mnHeaderSize
Maximum size of data slices (parts that cannot be split).
Definition: xestream.hxx:180
XclXmlUtils & operator=(const XclXmlUtils &)=delete
sax_fastparser::FSHelperPtr & GetCurrentStream()
Definition: xestream.cxx:911
void PopStream()
Definition: xestream.cxx:922
void UpdateRecSize()
Rewrites correct record length, if different from calculated.
Definition: xestream.cxx:388
void SetSliceSize(sal_uInt16 nSize)
Sets data slice length.
Definition: xestream.cxx:130
void Init(const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData)
Definition: xestream.cxx:545
XclExpEncrypterRef mxEncrypter
Definition: xestream.hxx:173
static sal_uInt32 GetBlockPos(std::size_t nStrmPos)
Definition: xestream.cxx:570
sal_uInt16 mnMaxRecSize
Definition: xestream.hxx:176
void restoreTabNames(const std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1215
std::size_t mnPredictSize
Count of bytes already written in current slice.
Definition: xestream.hxx:183
OptionalString sType
sal_uInt64 GetSvStreamPos() const
Returns the absolute position of the system stream.
Definition: xestream.hxx:140
XclExpXmlPathToStateMap maOpenedStreamMap
Definition: xestream.hxx:353
virtual oox::drawingml::chart::ChartConverter * getChartConverter() override
Definition: xestream.cxx:984
sal_uInt8 mpnSaltDigest[16]
Definition: xestream.hxx:225
A 2D cell range address list with Excel column and row indexes.
Definition: xladdress.hxx:100
void EndRecord()
Checks and corrects real record length.
Definition: xestream.cxx:121
sal_uInt8 mpnDocId[16]
Crypto algorithm implementation.
Definition: xestream.hxx:223
virtual ::oox::ole::VbaProject * implCreateVbaProject() const override
Definition: xestream.cxx:1129
void GetDocId(sal_uInt8 pnDocId[16]) const
Definition: xestream.cxx:485
A 2D cell address struct with Excel column and row indexes.
Definition: xladdress.hxx:29
XclExpStream & operator<<(sal_Int8 nValue)
Definition: xestream.cxx:136
void CopyFromStream(SvStream &rInStrm, sal_uInt64 nBytes=STREAM_SEEK_TO_END)
Copies nBytes bytes from current position of the stream rInStrm.
Definition: xestream.cxx:284
std::shared_ptr< FastSerializerHelper > FSHelperPtr
static sal_uInt16 GetOffsetInBlock(std::size_t nStrmPos)
Definition: xestream.cxx:575
void WriteByteString(const OString &rString)
Writes string length field and OString buffer.
Definition: xestream.cxx:329
FormulaError
XclXmlUtils()=delete
void SetSvStreamPos(sal_uInt64 nPos)
Sets position of system stream (only allowed outside of records).
Definition: xestream.cxx:369
static OUString GetStreamName(const char *sStreamDir, const char *sStream, sal_Int32 nId)
Definition: xestream.cxx:684
std::stack< sax_fastparser::FSHelperPtr > maStreams
Definition: xestream.hxx:352
void WriteZeroBytesToRecord(std::size_t nBytes)
Definition: xestream.cxx:274
void GetSalt(sal_uInt8 pnSalt[16]) const
Definition: xestream.cxx:479
void InitRecord(sal_uInt16 nRecId)
Writes header data, internal setup.
Definition: xestream.cxx:377
::std::vector< sal_uInt16 > ScfUInt16Vec
Definition: ftools.hxx:255
XclExpStream(SvStream &rOutStrm, const XclExpRoot &rRoot, sal_uInt16 nMaxRecSize=0)
Constructs the Excel record export stream.
Definition: xestream.cxx:85
unsigned char sal_uInt8
virtual oox::drawingml::table::TableStyleListPtr getTableStyles() override
Definition: xestream.cxx:979
std::map< OUString, std::pair< OUString, sax_fastparser::FSHelperPtr > > XclExpXmlPathToStateMap
Definition: xestream.hxx:349
std::size_t mnLastSizePos
Predicted size received from calling function.
Definition: xestream.hxx:186
void WriteRawZeroBytes(std::size_t nBytes)
Writes a raw sequence of zero bytes.
Definition: xestream.cxx:445
void WriteAttribute(sal_Int32 nAttr, const char *sVal)
Definition: xestream.hxx:337
sax_fastparser::FSHelperPtr CreateOutputStream(const OUString &sFullStream, const OUString &sRelativeStream, const css::uno::Reference< css::io::XOutputStream > &xParentRelation, const char *sContentType, std::u16string_view sRelationshipType, OUString *pRelationshipId=nullptr)
Definition: xestream.cxx:940
void UpdateSizeVars(std::size_t nSize)
Recalculates mnCurrSize and mnSliceSize.
Definition: xestream.cxx:397
bool mbExportTemplate
Definition: xestream.hxx:356
sal_uInt64 Tell() const
constexpr OUStringLiteral sStream
void WriteCharBuffer(const ScfUInt8Vec &rBuffer)
Writes 8-bit character buffer.
Definition: xestream.cxx:343
Any value
void DisableEncryption()
Definition: xestream.cxx:364
bool mbValid
Last known stream position.
Definition: xestream.hxx:228
bool IsValid() const
Definition: xestream.hxx:196
void renameTab(SCTAB aTab, OUString aNewName)
Definition: xestream.cxx:1234
void StartRecord(sal_uInt16 nRecId, std::size_t nRecSize)
Starts a new record: writes header data, stores calculated record size.
Definition: xestream.cxx:109
sal_uInt64 mnOldPos
Definition: xestream.hxx:227
void EnableEncryption(bool bEnable=true)
Definition: xestream.cxx:359
sal_Int32 nLength
const XclExpRoot & GetRoot() const
Returns the filter root data.
Definition: xestream.hxx:87
sal_uInt8 mpnSalt[16]
Definition: xestream.hxx:224
void WriteUnicodeBuffer(const ScfUInt16Vec &rBuffer, sal_uInt8 nFlags)
Writes Unicode buffer as 8/16 bit, repeats nFlags at start of a CONTINUE record.
Definition: xestream.cxx:306
XclExpBiff8Encrypter(const XclExpRoot &rRoot)
Definition: xestream.cxx:458
bool mbUseEncrypter
Filter root data.
Definition: xestream.hxx:172
sal_Int16 SCTAB
Definition: types.hxx:22
void WriteZeroBytes(std::size_t nBytes)
Writes a sequence of nBytes zero bytes (respects slice setting).
Definition: xestream.cxx:257
sal_uInt16 PrepareWrite()
Creates CONTINUE record at end of record.
Definition: xestream.cxx:430