LibreOffice Module sc (master)  1
xestream.cxx
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 #include <stdio.h>
21 #include <string.h>
22 #include <utility>
23 
24 #include <filter/msfilter/util.hxx>
25 #include <o3tl/safeint.hxx>
26 #include <osl/diagnose.h>
27 #include <rtl/ustring.hxx>
28 #include <rtl/ustrbuf.hxx>
29 #include <rtl/random.h>
30 #include <sax/fshelper.hxx>
31 #include <unotools/streamwrap.hxx>
32 #include <sot/storage.hxx>
33 #include <tools/urlobj.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/settings.hxx>
36 #include <officecfg/Office/Calc.hxx>
37 
38 #include <docuno.hxx>
39 #include <xestream.hxx>
40 #include <xladdress.hxx>
41 #include <xlstring.hxx>
42 #include <xltools.hxx>
43 #include <xeroot.hxx>
44 #include <xestring.hxx>
45 #include <xlstyle.hxx>
46 #include <rangelst.hxx>
47 #include <compiler.hxx>
48 #include <formulacell.hxx>
49 #include <tokenarray.hxx>
50 #include <tokenstringcontext.hxx>
52 #include <globstr.hrc>
53 #include <scresid.hxx>
54 #include <root.hxx>
55 #include <sfx2/app.hxx>
56 
57 #include <docsh.hxx>
58 #include <viewdata.hxx>
59 #include <excdoc.hxx>
60 
61 #include <oox/token/tokens.hxx>
63 #include <oox/export/drawingml.hxx>
64 #include <oox/export/utils.hxx>
65 #include <formula/grammar.hxx>
66 #include <oox/ole/vbaexport.hxx>
67 #include <excelvbaproject.hxx>
68 
69 #include <com/sun/star/task/XStatusIndicator.hpp>
70 #include <memory>
72 
73 #include <externalrefmgr.hxx>
74 
75 #define DEBUG_XL_ENCRYPTION 0
76 
77 using ::com::sun::star::uno::XInterface;
78 using ::std::vector;
79 
80 using namespace com::sun::star;
81 using namespace ::com::sun::star::beans;
82 using namespace ::com::sun::star::io;
83 using namespace ::com::sun::star::lang;
84 using namespace ::com::sun::star::sheet;
85 using namespace ::com::sun::star::uno;
86 using namespace ::formula;
87 using namespace ::oox;
88 
89 XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
90  mrStrm( rOutStrm ),
91  mrRoot( rRoot ),
92  mbUseEncrypter( false ),
93  mnMaxRecSize( nMaxRecSize ),
94  mnCurrMaxSize( 0 ),
95  mnMaxSliceSize( 0 ),
96  mnHeaderSize( 0 ),
97  mnCurrSize( 0 ),
98  mnSliceSize( 0 ),
99  mnPredictSize( 0 ),
100  mnLastSizePos( 0 ),
101  mbInRec( false )
102 {
103  if( mnMaxRecSize == 0 )
106 }
107 
109 {
111 }
112 
113 void XclExpStream::StartRecord( sal_uInt16 nRecId, std::size_t nRecSize )
114 {
115  OSL_ENSURE( !mbInRec, "XclExpStream::StartRecord - another record still open" );
118  mnPredictSize = nRecSize;
119  mbInRec = true;
120  InitRecord( nRecId );
121  SetSliceSize( 0 );
123 }
124 
126 {
127  OSL_ENSURE( mbInRec, "XclExpStream::EndRecord - no record open" );
129  UpdateRecSize();
131  mbInRec = false;
132 }
133 
134 void XclExpStream::SetSliceSize( sal_uInt16 nSize )
135 {
136  mnMaxSliceSize = nSize;
137  mnSliceSize = 0;
138 }
139 
141 {
142  PrepareWrite( 1 );
144  mxEncrypter->Encrypt(mrStrm, nValue);
145  else
146  mrStrm.WriteSChar( nValue );
147  return *this;
148 }
149 
151 {
152  PrepareWrite( 1 );
154  mxEncrypter->Encrypt(mrStrm, nValue);
155  else
156  mrStrm.WriteUChar( nValue );
157  return *this;
158 }
159 
161 {
162  PrepareWrite( 2 );
164  mxEncrypter->Encrypt(mrStrm, nValue);
165  else
166  mrStrm.WriteInt16( nValue );
167  return *this;
168 }
169 
171 {
172  PrepareWrite( 2 );
174  mxEncrypter->Encrypt(mrStrm, nValue);
175  else
176  mrStrm.WriteUInt16( nValue );
177  return *this;
178 }
179 
181 {
182  PrepareWrite( 4 );
184  mxEncrypter->Encrypt(mrStrm, nValue);
185  else
186  mrStrm.WriteInt32( nValue );
187  return *this;
188 }
189 
191 {
192  PrepareWrite( 4 );
194  mxEncrypter->Encrypt(mrStrm, nValue);
195  else
196  mrStrm.WriteUInt32( nValue );
197  return *this;
198 }
199 
201 {
202  PrepareWrite( 4 );
204  mxEncrypter->Encrypt(mrStrm, fValue);
205  else
206  mrStrm.WriteFloat( fValue );
207  return *this;
208 }
209 
211 {
212  PrepareWrite( 8 );
214  mxEncrypter->Encrypt(mrStrm, fValue);
215  else
216  mrStrm.WriteDouble( fValue );
217  return *this;
218 }
219 
220 std::size_t XclExpStream::Write( const void* pData, std::size_t nBytes )
221 {
222  std::size_t nRet = 0;
223  if( pData && (nBytes > 0) )
224  {
225  if( mbInRec )
226  {
227  const sal_uInt8* pBuffer = static_cast< const sal_uInt8* >( pData );
228  std::size_t nBytesLeft = nBytes;
229  bool bValid = true;
230 
231  while( bValid && (nBytesLeft > 0) )
232  {
233  std::size_t nWriteLen = ::std::min< std::size_t >( PrepareWrite(), nBytesLeft );
234  std::size_t nWriteRet = nWriteLen;
236  {
237  OSL_ENSURE(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
238  vector<sal_uInt8> aBytes(nWriteLen);
239  memcpy(aBytes.data(), pBuffer, nWriteLen);
240  mxEncrypter->EncryptBytes(mrStrm, aBytes);
241  // TODO: How do I check if all the bytes have been successfully written ?
242  }
243  else
244  {
245  nWriteRet = mrStrm.WriteBytes(pBuffer, nWriteLen);
246  bValid = (nWriteLen == nWriteRet);
247  OSL_ENSURE( bValid, "XclExpStream::Write - stream write error" );
248  }
249  pBuffer += nWriteRet;
250  nRet += nWriteRet;
251  nBytesLeft -= nWriteRet;
252  UpdateSizeVars( nWriteRet );
253  }
254  }
255  else
256  nRet = mrStrm.WriteBytes(pData, nBytes);
257  }
258  return nRet;
259 }
260 
261 void XclExpStream::WriteZeroBytes( std::size_t nBytes )
262 {
263  if( mbInRec )
264  {
265  std::size_t nBytesLeft = nBytes;
266  while( nBytesLeft > 0 )
267  {
268  std::size_t nWriteLen = ::std::min< std::size_t >( PrepareWrite(), nBytesLeft );
269  WriteRawZeroBytes( nWriteLen );
270  nBytesLeft -= nWriteLen;
271  UpdateSizeVars( nWriteLen );
272  }
273  }
274  else
275  WriteRawZeroBytes( nBytes );
276 }
277 
278 void XclExpStream::WriteZeroBytesToRecord( std::size_t nBytes )
279 {
280  if (!mbInRec)
281  // not in record.
282  return;
283 
284  for (std::size_t i = 0; i < nBytes; ++i)
285  *this << sal_uInt8(0)/*nZero*/;
286 }
287 
288 void XclExpStream::CopyFromStream(SvStream& rInStrm, sal_uInt64 const nBytes)
289 {
290  sal_uInt64 const nRemaining(rInStrm.remainingSize());
291  sal_uInt64 nBytesLeft = ::std::min(nBytes, nRemaining);
292  if( nBytesLeft <= 0 )
293  return;
294 
295  const std::size_t nMaxBuffer = 4096;
296  std::unique_ptr<sal_uInt8[]> pBuffer(
297  new sal_uInt8[ ::std::min<std::size_t>(nBytesLeft, nMaxBuffer) ]);
298  bool bValid = true;
299 
300  while( bValid && (nBytesLeft > 0) )
301  {
302  std::size_t nWriteLen = ::std::min<std::size_t>(nBytesLeft, nMaxBuffer);
303  rInStrm.ReadBytes(pBuffer.get(), nWriteLen);
304  std::size_t nWriteRet = Write( pBuffer.get(), nWriteLen );
305  bValid = (nWriteLen == nWriteRet);
306  nBytesLeft -= nWriteRet;
307  }
308 }
309 
311 {
312  SetSliceSize( 0 );
313  nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
314  sal_uInt16 nCharLen = nFlags ? 2 : 1;
315 
316  for( const auto& rItem : rBuffer )
317  {
318  if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
319  {
320  StartContinue();
321  operator<<( nFlags );
322  }
323  if( nCharLen == 2 )
324  operator<<( rItem );
325  else
326  operator<<( static_cast< sal_uInt8 >( rItem ) );
327  }
328 }
329 
330 // Xcl has an obscure sense of whether starting a new record or not,
331 // and crashes if it encounters the string header at the very end of a record.
332 // Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
333 void XclExpStream::WriteByteString( const OString& rString )
334 {
335  SetSliceSize( 0 );
336  std::size_t nLen = ::std::min< std::size_t >( rString.getLength(), 0x00FF );
337  nLen = ::std::min< std::size_t >( nLen, 0xFF );
338 
339  sal_uInt16 nLeft = PrepareWrite();
340  if( mbInRec && (nLeft <= 1) )
341  StartContinue();
342 
343  operator<<( static_cast< sal_uInt8 >( nLen ) );
344  Write( rString.getStr(), nLen );
345 }
346 
348 {
349  SetSliceSize( 0 );
350  Write( rBuffer.data(), rBuffer.size() );
351 }
352 
354 {
355  mxEncrypter = xEncrypter;
356 }
357 
359 {
360  return mxEncrypter && mxEncrypter->IsValid();
361 }
362 
363 void XclExpStream::EnableEncryption( bool bEnable )
364 {
365  mbUseEncrypter = bEnable && HasValidEncrypter();
366 }
367 
369 {
370  EnableEncryption(false);
371 }
372 
373 void XclExpStream::SetSvStreamPos(sal_uInt64 const nPos)
374 {
375  OSL_ENSURE( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
376  mbInRec ? 0 : mrStrm.Seek( nPos );
377 }
378 
379 // private --------------------------------------------------------------------
380 
381 void XclExpStream::InitRecord( sal_uInt16 nRecId )
382 {
384  mrStrm.WriteUInt16( nRecId );
385 
387  mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< std::size_t >( mnPredictSize, mnCurrMaxSize ) );
389  mnCurrSize = mnSliceSize = 0;
390 }
391 
393 {
394  if( mnCurrSize != mnHeaderSize )
395  {
398  }
399 }
400 
401 void XclExpStream::UpdateSizeVars( std::size_t nSize )
402 {
403  OSL_ENSURE( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
404  mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
405 
406  if( mnMaxSliceSize > 0 )
407  {
408  OSL_ENSURE( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
409  mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
410  if( mnSliceSize >= mnMaxSliceSize )
411  mnSliceSize = 0;
412  }
413 }
414 
416 {
417  UpdateRecSize();
421 }
422 
423 void XclExpStream::PrepareWrite( sal_uInt16 nSize )
424 {
425  if( mbInRec )
426  {
427  if( (mnCurrSize + nSize > mnCurrMaxSize) ||
429  StartContinue();
430  UpdateSizeVars( nSize );
431  }
432 }
433 
435 {
436  sal_uInt16 nRet = 0;
437  if( mbInRec )
438  {
439  if( (mnCurrSize >= mnCurrMaxSize) ||
441  StartContinue();
442  UpdateSizeVars( 0 );
443 
445  }
446  return nRet;
447 }
448 
449 void XclExpStream::WriteRawZeroBytes( std::size_t nBytes )
450 {
451  const sal_uInt32 nData = 0;
452  std::size_t nBytesLeft = nBytes;
453  while( nBytesLeft >= sizeof( nData ) )
454  {
455  mrStrm.WriteUInt32( nData );
456  nBytesLeft -= sizeof( nData );
457  }
458  if( nBytesLeft )
459  mrStrm.WriteBytes(&nData, nBytesLeft);
460 }
461 
463  mnOldPos(STREAM_SEEK_TO_END),
464  mbValid(false)
465 {
466  Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData();
467  if( !aEncryptionData.hasElements() )
468  // Empty password. Get the default biff8 password.
469  aEncryptionData = XclExpRoot::GenerateDefaultEncryptionData();
470  Init( aEncryptionData );
471 }
472 
474 {
475 }
476 
477 void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const
478 {
479  if ( sizeof( mpnSaltDigest ) == 16 )
480  memcpy( pnSaltDigest, mpnSaltDigest, 16 );
481 }
482 
483 void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const
484 {
485  if ( sizeof( mpnSalt ) == 16 )
486  memcpy( pnSalt, mpnSalt, 16 );
487 }
488 
489 void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const
490 {
491  if ( sizeof( mpnDocId ) == 16 )
492  memcpy( pnDocId, mpnDocId, 16 );
493 }
494 
496 {
497  vector<sal_uInt8> aByte { nData };
498  EncryptBytes(rStrm, aByte);
499 }
500 
501 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
502 {
503  ::std::vector<sal_uInt8> pnBytes
504  {
505  o3tl::narrowing<sal_uInt8>(nData & 0xFF),
506  o3tl::narrowing<sal_uInt8>((nData >> 8) & 0xFF)
507  };
508  EncryptBytes(rStrm, pnBytes);
509 }
510 
511 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
512 {
513  ::std::vector<sal_uInt8> pnBytes
514  {
515  o3tl::narrowing<sal_uInt8>(nData & 0xFF),
516  o3tl::narrowing<sal_uInt8>((nData >> 8) & 0xFF),
517  o3tl::narrowing<sal_uInt8>((nData >> 16) & 0xFF),
518  o3tl::narrowing<sal_uInt8>((nData >> 24) & 0xFF)
519  };
520  EncryptBytes(rStrm, pnBytes);
521 }
522 
523 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
524 {
525  ::std::vector<sal_uInt8> pnBytes(4);
526  memcpy(pnBytes.data(), &fValue, 4);
527  EncryptBytes(rStrm, pnBytes);
528 }
529 
530 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
531 {
532  ::std::vector<sal_uInt8> pnBytes(8);
533  memcpy(pnBytes.data(), &fValue, 8);
534  EncryptBytes(rStrm, pnBytes);
535 }
536 
538 {
539  Encrypt(rStrm, static_cast<sal_uInt8>(nData));
540 }
541 
542 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
543 {
544  Encrypt(rStrm, static_cast<sal_uInt16>(nData));
545 }
546 
547 void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
548 {
549  Encrypt(rStrm, static_cast<sal_uInt32>(nData));
550 }
551 
552 void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
553 {
554  mbValid = false;
555 
556  if( !maCodec.InitCodec( rEncryptionData ) )
557  return;
558 
560 
561  // generate the salt here
562  rtlRandomPool aRandomPool = rtl_random_createPool ();
563  rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
564  rtl_random_destroyPool( aRandomPool );
565 
566  memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
567 
568  // generate salt hash.
570  aCodec.InitCodec( rEncryptionData );
572 
573  // verify to make sure it's in good shape.
575 }
576 
577 sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( std::size_t nStrmPos )
578 {
579  return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
580 }
581 
582 sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( std::size_t nStrmPos )
583 {
584  return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
585 }
586 
587 void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
588 {
589  sal_uInt64 nStrmPos = rStrm.Tell();
590  sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
591  sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
592 
593 #if DEBUG_XL_ENCRYPTION
594  fprintf(stdout, "XclExpBiff8Encrypter::EncryptBytes: stream pos = %ld offset in block = %d block pos = %ld\n",
595  nStrmPos, nBlockOffset, nBlockPos);
596 #endif
597 
598  sal_uInt16 nSize = static_cast< sal_uInt16 >( aBytes.size() );
599  if (nSize == 0)
600  return;
601 
602 #if DEBUG_XL_ENCRYPTION
603  fprintf(stdout, "RAW: ");
604  for (sal_uInt16 i = 0; i < nSize; ++i)
605  fprintf(stdout, "%2.2X ", aBytes[i]);
606  fprintf(stdout, "\n");
607 #endif
608 
609  if (mnOldPos != nStrmPos)
610  {
611  sal_uInt16 nOldOffset = GetOffsetInBlock(mnOldPos);
612  sal_uInt32 nOldBlockPos = GetBlockPos(mnOldPos);
613 
614  if ( (nBlockPos != nOldBlockPos) || (nBlockOffset < nOldOffset) )
615  {
616  maCodec.InitCipher(nBlockPos);
617  nOldOffset = 0;
618  }
619 
620  if (nBlockOffset > nOldOffset)
621  maCodec.Skip(nBlockOffset - nOldOffset);
622  }
623 
624  sal_uInt16 nBytesLeft = nSize;
625  sal_uInt16 nPos = 0;
626  while (nBytesLeft > 0)
627  {
628  sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - nBlockOffset;
629  sal_uInt16 nEncBytes = ::std::min(nBlockLeft, nBytesLeft);
630 
631  bool bRet = maCodec.Encode(&aBytes[nPos], nEncBytes, &aBytes[nPos], nEncBytes);
632  OSL_ENSURE(bRet, "XclExpBiff8Encrypter::EncryptBytes: encryption failed!!");
633 
634  std::size_t nRet = rStrm.WriteBytes(&aBytes[nPos], nEncBytes);
635  OSL_ENSURE(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
636 
637  nStrmPos = rStrm.Tell();
638  nBlockOffset = GetOffsetInBlock(nStrmPos);
639  nBlockPos = GetBlockPos(nStrmPos);
640  if (nBlockOffset == 0)
641  maCodec.InitCipher(nBlockPos);
642 
643  nBytesLeft -= nEncBytes;
644  nPos += nEncBytes;
645  }
646  mnOldPos = nStrmPos;
647 }
648 
649 static const char* lcl_GetErrorString( FormulaError nScErrCode )
650 {
651  sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
652  switch( nXclErrCode )
653  {
654  case EXC_ERR_NULL: return "#NULL!";
655  case EXC_ERR_DIV0: return "#DIV/0!";
656  case EXC_ERR_VALUE: return "#VALUE!";
657  case EXC_ERR_REF: return "#REF!";
658  case EXC_ERR_NAME: return "#NAME?";
659  case EXC_ERR_NUM: return "#NUM!";
660  case EXC_ERR_NA:
661  default: return "#N/A";
662  }
663 }
664 
665 void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
666 {
667  sc::FormulaResultValue aResValue = rCell.GetResult();
668 
669  switch (aResValue.meType)
670  {
672  rsType = "e";
673  rsValue = ToOUString(lcl_GetErrorString(aResValue.mnError));
674  break;
676  rsType = rCell.GetFormatType() == SvNumFormatType::LOGICAL
677  && (aResValue.mfValue == 0.0 || aResValue.mfValue == 1.0)
678  ? "b"
679  : "n";
680  rsValue = OUString::number(aResValue.mfValue);
681  break;
683  rsType = "str";
684  rsValue = rCell.GetString().getString();
685  break;
687  default:
688  // TODO : double-check this to see if this is correct.
689  rsType = "inlineStr";
690  rsValue = rCell.GetString().getString();
691  }
692 }
693 
694 OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
695 {
696  OUStringBuffer sBuf;
697  if( sStreamDir )
698  sBuf.appendAscii( sStreamDir );
699  sBuf.appendAscii( sStream );
700  if( nId )
701  sBuf.append( nId );
702  if( strstr(sStream, "vml") )
703  sBuf.append( ".vml" );
704  else
705  sBuf.append( ".xml" );
706  return sBuf.makeStringAndClear();
707 }
708 
709 OString XclXmlUtils::ToOString( const Color& rColor )
710 {
711  char buf[9];
712  sprintf( buf, "%.2X%.2X%.2X%.2X", rColor.GetAlpha(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
713  buf[8] = '\0';
714  return OString(buf);
715 }
716 
717 OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const ScAddress& rAddress )
718 {
719  rAddress.Format(s, ScRefFlags::VALID, nullptr, ScAddress::Details( FormulaGrammar::CONV_XL_A1));
720  return s;
721 }
722 
723 OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
724 {
725  if(rBuffer.empty())
726  return OString();
727 
728  const sal_uInt16* pBuffer = rBuffer.data();
729  return OString(
730  reinterpret_cast<sal_Unicode const *>(pBuffer), rBuffer.size(),
731  RTL_TEXTENCODING_UTF8);
732 }
733 
734 OString XclXmlUtils::ToOString( const ScDocument& rDoc, const ScRange& rRange, bool bFullAddressNotation )
735 {
736  OUString sRange(rRange.Format( rDoc, ScRefFlags::VALID,
737  ScAddress::Details( FormulaGrammar::CONV_XL_A1 ),
738  bFullAddressNotation ) );
739  return sRange.toUtf8();
740 }
741 
742 OString XclXmlUtils::ToOString( const ScDocument& rDoc, const ScRangeList& rRangeList )
743 {
744  OUString s;
745  rRangeList.Format(s, ScRefFlags::VALID, rDoc, FormulaGrammar::CONV_XL_OOX, ' ');
746  return s.toUtf8();
747 }
748 
749 static ScAddress lcl_ToAddress( const XclAddress& rAddress )
750 {
751  return ScAddress( rAddress.mnCol, rAddress.mnRow, 0 );
752 }
753 
754 OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const XclAddress& rAddress )
755 {
756  return ToOString( s, lcl_ToAddress( rAddress ));
757 }
758 
760 {
761  OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
762  return ToOString( s.GetUnicodeBuffer() );
763 }
764 
765 static ScRange lcl_ToRange( const XclRange& rRange )
766 {
767  ScRange aRange;
768 
769  aRange.aStart = lcl_ToAddress( rRange.maFirst );
770  aRange.aEnd = lcl_ToAddress( rRange.maLast );
771 
772  return aRange;
773 }
774 
775 OString XclXmlUtils::ToOString( const ScDocument& rDoc, const XclRangeList& rRanges )
776 {
777  ScRangeList aRanges;
778  for( const auto& rRange : rRanges )
779  {
780  aRanges.push_back( lcl_ToRange( rRange ) );
781  }
782  return ToOString( rDoc, aRanges );
783 }
784 
785 OUString XclXmlUtils::ToOUString( const char* s )
786 {
787  return OUString( s, static_cast<sal_Int32>(strlen( s )), RTL_TEXTENCODING_ASCII_US );
788 }
789 
790 OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
791 {
792  if( nLength == -1 || ( nLength > (static_cast<sal_Int32>(rBuf.size()) - nStart) ) )
793  nLength = (rBuf.size() - nStart);
794 
795  return nLength > 0
796  ? OUString(
797  reinterpret_cast<sal_Unicode const *>(&rBuf[nStart]), nLength)
798  : OUString();
799 }
800 
802  sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray,
803  FormulaError nErrCode )
804 {
805  ScCompiler aCompiler( rCtx, rAddress, const_cast<ScTokenArray&>(*pTokenArray));
806 
807  /* TODO: isn't this the same as passed in rCtx and thus superfluous? */
808  aCompiler.SetGrammar(FormulaGrammar::GRAM_OOXML);
809 
810  sal_Int32 nLen = pTokenArray->GetLen();
811  OUStringBuffer aBuffer( nLen ? (nLen * 5) : 8 );
812  if (nLen)
813  aCompiler.CreateStringFromTokenArray( aBuffer );
814  else
815  {
816  if (nErrCode != FormulaError::NONE)
817  aCompiler.AppendErrorConstant( aBuffer, nErrCode);
818  else
819  {
820  // No code SHOULD be an "error cell", assert caller thought of that
821  // and it really is.
822  assert(!"No code and no error.");
823  }
824  }
825 
826  return aBuffer.makeStringAndClear();
827 }
828 
830 {
831  OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
832  return ToOUString( s.GetUnicodeBuffer() );
833 }
834 
835 static void lcl_WriteValue( const sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
836 {
837  if( !pValue )
838  return;
839  rStream->singleElement(nElement, XML_val, pValue);
840 }
841 
842 static const char* lcl_GetUnderlineStyle( FontLineStyle eUnderline, bool& bHaveUnderline )
843 {
844  bHaveUnderline = true;
845  switch( eUnderline )
846  {
847  // OOXTODO: doubleAccounting, singleAccounting
848  // OOXTODO: what should be done with the other FontLineStyle values?
849  case LINESTYLE_SINGLE: return "single";
850  case LINESTYLE_DOUBLE: return "double";
851  case LINESTYLE_NONE:
852  default: bHaveUnderline = false; return "none";
853  }
854 }
855 
856 static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
857 {
858  bHaveAlignment = true;
859  switch( eEscapement )
860  {
861  case SvxEscapement::Superscript: return "superscript";
862  case SvxEscapement::Subscript: return "subscript";
863  case SvxEscapement::Off:
864  default: bHaveAlignment = false; return "baseline";
865  }
866 }
867 
869 {
870  bool bHaveUnderline, bHaveVertAlign;
871  const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
872  const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
873 
874  lcl_WriteValue( pStream, XML_b, rFontData.mnWeight > 400 ? ToPsz( true ) : nullptr );
875  lcl_WriteValue( pStream, XML_i, rFontData.mbItalic ? ToPsz( true ) : nullptr );
876  lcl_WriteValue( pStream, XML_strike, rFontData.mbStrikeout ? ToPsz( true ) : nullptr );
877  // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
878  // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
879  lcl_WriteValue( pStream, XML_outline, rFontData.mbOutline ? ToPsz( true ) : nullptr );
880  lcl_WriteValue( pStream, XML_shadow, rFontData.mbShadow ? ToPsz( true ) : nullptr );
881  lcl_WriteValue( pStream, XML_u, bHaveUnderline ? pUnderline : nullptr );
882  lcl_WriteValue( pStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : nullptr );
883  lcl_WriteValue( pStream, XML_sz, OString::number( rFontData.mnHeight / 20.0 ).getStr() ); // Twips->Pt
884  if( rFontData.maColor != Color( ColorAlpha, 0, 0xFF, 0xFF, 0xFF ) )
885  pStream->singleElement( XML_color,
886  // OOXTODO: XML_auto, bool
887  // OOXTODO: XML_indexed, uint
888  XML_rgb, XclXmlUtils::ToOString(rFontData.maColor)
889  // OOXTODO: XML_theme, index into <clrScheme/>
890  // OOXTODO: XML_tint, double
891  );
892  lcl_WriteValue( pStream, nFontId, rFontData.maName.toUtf8().getStr() );
893  lcl_WriteValue( pStream, XML_family, OString::number( rFontData.mnFamily ).getStr() );
894  lcl_WriteValue( pStream, XML_charset, rFontData.mnCharSet != 0 ? OString::number( rFontData.mnCharSet ).getStr() : nullptr );
895 
896  return pStream;
897 }
898 
899 XclExpXmlStream::XclExpXmlStream( const uno::Reference< XComponentContext >& rCC, bool bExportVBA, bool bExportTemplate )
900  : XmlFilterBase( rCC ),
901  mpRoot( nullptr ),
902  mbExportVBA(bExportVBA),
903  mbExportTemplate(bExportTemplate)
904 {
905 }
906 
908 {
909  assert(maStreams.empty() && "Forgotten PopStream()?");
910 }
911 
913 {
914  OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
915  return maStreams.top();
916 }
917 
919 {
920  maStreams.push( aStream );
921 }
922 
924 {
925  OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
926  maStreams.pop();
927 }
928 
930 {
931  if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
933  return maOpenedStreamMap[ sPath ].second;
934 }
935 
936 void XclExpXmlStream::WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal)
937 {
938  GetCurrentStream()->write(" ")->writeId(nAttr)->write("=\"")->writeEscaped(sVal)->write("\"");
939 }
940 
942  const OUString& sFullStream,
943  std::u16string_view sRelativeStream,
944  const uno::Reference< XOutputStream >& xParentRelation,
945  const char* sContentType,
946  std::u16string_view sRelationshipType,
947  OUString* pRelationshipId )
948 {
949  OUString sRelationshipId;
950  if (xParentRelation.is())
951  sRelationshipId = addRelation( xParentRelation, OUString(sRelationshipType), sRelativeStream );
952  else
953  sRelationshipId = addRelation( OUString(sRelationshipType), sRelativeStream );
954 
955  if( pRelationshipId )
956  *pRelationshipId = sRelationshipId;
957 
958  sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
959 
960  maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
961 
962  return p;
963 }
964 
966 {
967  return false;
968 }
969 
971 {
972  return nullptr;
973 }
974 
976 {
977  return nullptr;
978 }
979 
981 {
983 }
984 
986 {
987  // DO NOT CALL
988  return nullptr;
989 }
990 
992 {
993  uno::Reference< XInterface > xModel( getModel(), UNO_QUERY );
994 
995  ScModelObj *pObj = dynamic_cast < ScModelObj* >( xModel.get() );
996 
997  if ( pObj )
998  return static_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
999 
1000  return nullptr;
1001 }
1002 
1004 {
1005  ScDocShell* pShell = getDocShell();
1006  ScDocument& rDoc = pShell->GetDocument();
1008 
1009  const bool bValidateTabNames = officecfg::Office::Calc::Filter::Export::MS_Excel::TruncateLongSheetNames::get();
1010  std::vector<OUString> aOriginalTabNames;
1011  if (bValidateTabNames)
1012  {
1013  validateTabNames(aOriginalTabNames);
1014  }
1015 
1016  uno::Reference<task::XStatusIndicator> xStatusIndicator = getStatusIndicator();
1017 
1018  if (xStatusIndicator.is())
1019  xStatusIndicator->start(ScResId(STR_SAVE_DOC), 100);
1020 
1021  // NOTE: Don't use SotStorage or SvStream any more, and never call
1022  // SfxMedium::GetOutStream() anywhere in the xlsx export filter code!
1023  // Instead, write via XOutputStream instance.
1024  tools::SvRef<SotStorage> rStorage = static_cast<SotStorage*>(nullptr);
1025  drawingml::DrawingML::ResetMlCounters();
1026  drawingml::DrawingML::PushExportGraphics();
1027 
1029  EXC_BIFF8, *pShell->GetMedium (), rStorage, rDoc,
1031  Application::GetSettings().GetLanguageTag().getLocale()));
1032  aData.meOutput = EXC_OUTPUT_XML_2007;
1034  aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
1035  aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
1036  aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
1037  aData.mpCompileFormulaCxt = std::make_shared<sc::CompileFormulaContext>(rDoc);
1038  // set target path to get correct relative links to target document, not source
1039  INetURLObject aPath(getFileUrl());
1040  aData.maBasePath = OUString("file:///" + aPath.GetPath() + "\\").replace('\\', '/')
1041  // fix for Linux
1042  .replaceFirst("file:////", "file:///");
1043 
1044  XclExpRoot aRoot( aData );
1045 
1046  mpRoot = &aRoot;
1047  aRoot.GetOldRoot().pER = &aRoot;
1048  aRoot.GetOldRoot().eDateiTyp = Biff8;
1049  // Get the viewsettings before processing
1050  if( ScDocShell::GetViewData() )
1052 
1053  OUString const workbook = "xl/workbook.xml";
1054  const char* pWorkbookContentType = nullptr;
1055  if (mbExportVBA)
1056  {
1057  if (mbExportTemplate)
1058  {
1059  pWorkbookContentType = "application/vnd.ms-excel.template.macroEnabled.main+xml";
1060  }
1061  else
1062  {
1063  pWorkbookContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml";
1064  }
1065  }
1066  else
1067  {
1068  if (mbExportTemplate)
1069  {
1070  pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml";
1071  }
1072  else
1073  {
1074  pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
1075  }
1076  }
1077 
1078  PushStream( CreateOutputStream( workbook, workbook,
1079  uno::Reference <XOutputStream>(),
1080  pWorkbookContentType,
1081  oox::getRelationship(Relationship::OFFICEDOCUMENT) ) );
1082 
1083  if (mbExportVBA)
1084  {
1085  VbaExport aExport(getModel());
1086  if (aExport.containsVBAProject())
1087  {
1088  SvMemoryStream aVbaStream(4096, 4096);
1089  tools::SvRef<SotStorage> pVBAStorage(new SotStorage(aVbaStream));
1090  aExport.exportVBA( pVBAStorage.get() );
1091  aVbaStream.Seek(0);
1092  css::uno::Reference<css::io::XInputStream> xVBAStream(
1093  new utl::OInputStreamWrapper(aVbaStream));
1094  css::uno::Reference<css::io::XOutputStream> xVBAOutput =
1095  openFragmentStream("xl/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1096  comphelper::OStorageHelper::CopyInputToOutput(xVBAStream, xVBAOutput);
1097 
1098  addRelation(GetCurrentStream()->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), u"vbaProject.bin");
1099  }
1100  }
1101 
1102  // destruct at the end of the block
1103  {
1104  ExcDocument aDocRoot( aRoot );
1105  if (xStatusIndicator.is())
1106  xStatusIndicator->setValue(10);
1107  aDocRoot.ReadDoc();
1108  if (xStatusIndicator.is())
1109  xStatusIndicator->setValue(40);
1110  aDocRoot.WriteXml( *this );
1111  rDoc.GetExternalRefManager()->disableSkipUnusedFileIds();
1112  }
1113 
1114  PopStream();
1115  // Free all FSHelperPtr, to flush data before committing storage
1116  maOpenedStreamMap.clear();
1117 
1118  commitStorage();
1119 
1120  if (bValidateTabNames)
1121  {
1122  restoreTabNames(aOriginalTabNames);
1123  }
1124 
1125  if (xStatusIndicator.is())
1126  xStatusIndicator->end();
1127  mpRoot = nullptr;
1128 
1129  drawingml::DrawingML::PopExportGraphics();
1130 
1131  return true;
1132 }
1133 
1135 {
1136  return new ::oox::xls::ExcelVbaProject( getComponentContext(), uno::Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
1137 }
1138 
1140 {
1141  return "TODO";
1142 }
1143 
1144 void XclExpXmlStream::validateTabNames(std::vector<OUString>& aOriginalTabNames)
1145 {
1146  const int MAX_TAB_NAME_LENGTH = 31;
1147 
1148  ScDocShell* pShell = getDocShell();
1149  ScDocument& rDoc = pShell->GetDocument();
1150 
1151  // get original names
1152  aOriginalTabNames.resize(rDoc.GetTableCount());
1153  for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1154  {
1155  rDoc.GetName(nTab, aOriginalTabNames[nTab]);
1156  }
1157 
1158  // new tab names
1159  std::vector<OUString> aNewTabNames;
1160  aNewTabNames.reserve(rDoc.GetTableCount());
1161 
1162  // check and rename
1163  for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1164  {
1165  const OUString& rOriginalName = aOriginalTabNames[nTab];
1166  if (rOriginalName.getLength() > MAX_TAB_NAME_LENGTH)
1167  {
1168  OUString aNewName;
1169 
1170  // let's try just truncate "<first 31 chars>"
1171  if (aNewName.isEmpty())
1172  {
1173  aNewName = rOriginalName.copy(0, MAX_TAB_NAME_LENGTH);
1174  if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
1175  aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
1176  {
1177  // was found => let's use another tab name
1178  aNewName.clear();
1179  }
1180  }
1181 
1182  // let's try "<first N chars>-XXX" template
1183  for (int digits=1; digits<10 && aNewName.isEmpty(); digits++)
1184  {
1185  const int rangeStart = pow(10, digits - 1);
1186  const int rangeEnd = pow(10, digits);
1187 
1188  for (int i=rangeStart; i<rangeEnd && aNewName.isEmpty(); i++)
1189  {
1190  aNewName = OUString::Concat(rOriginalName.subView(0, MAX_TAB_NAME_LENGTH - 1 - digits)) + "-" + OUString::number(i);
1191  if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
1192  aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
1193  {
1194  // was found => let's use another tab name
1195  aNewName.clear();
1196  }
1197  }
1198  }
1199 
1200  if (!aNewName.isEmpty())
1201  {
1202  // new name was created => rename
1203  renameTab(nTab, aNewName);
1204  aNewTabNames.push_back(aNewName);
1205  }
1206  else
1207  {
1208  // default: do not rename
1209  aNewTabNames.push_back(rOriginalName);
1210  }
1211  }
1212  else
1213  {
1214  // default: do not rename
1215  aNewTabNames.push_back(rOriginalName);
1216  }
1217  }
1218 }
1219 
1220 void XclExpXmlStream::restoreTabNames(const std::vector<OUString>& aOriginalTabNames)
1221 {
1222  ScDocShell* pShell = getDocShell();
1223  ScDocument& rDoc = pShell->GetDocument();
1224 
1225  for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1226  {
1227  const OUString& rOriginalName = aOriginalTabNames[nTab];
1228 
1229  OUString rModifiedName;
1230  rDoc.GetName(nTab, rModifiedName);
1231 
1232  if (rOriginalName != rModifiedName)
1233  {
1234  renameTab(nTab, rOriginalName);
1235  }
1236  }
1237 }
1238 
1239 void XclExpXmlStream::renameTab(SCTAB aTab, OUString aNewName)
1240 {
1241  ScDocShell* pShell = getDocShell();
1242  ScDocument& rDoc = pShell->GetDocument();
1243 
1244  bool bAutoCalcShellDisabled = rDoc.IsAutoCalcShellDisabled();
1245  bool bIdleEnabled = rDoc.IsIdleEnabled();
1246 
1247  rDoc.SetAutoCalcShellDisabled( true );
1248  rDoc.EnableIdle(false);
1249 
1250  if (rDoc.RenameTab(aTab, aNewName))
1251  {
1252  SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged));
1253  }
1254 
1255  rDoc.SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
1256  rDoc.EnableIdle(bIdleEnabled);
1257 }
1258 
1259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual const oox::drawingml::Theme * getCurrentTheme() const override
Definition: xestream.cxx:975
This class stores an unformatted or formatted string for Excel export.
Definition: xestring.hxx:47
const sal_uInt8 EXC_ERR_NULL
DDE application-topic delimiter.
Definition: xlconst.hxx:104
void GetSaltDigest(sal_uInt8 pnSaltDigest[16]) const
Definition: xestream.cxx:477
void EnableIdle(bool bDo)
Definition: document.hxx:2202
virtual oox::vml::Drawing * getVmlDrawing() override
Definition: xestream.cxx:970
bool InitCodec(const css::uno::Sequence< css::beans::NamedValue > &aData)
void StartContinue()
Writes CONTINUE header, internal setup.
Definition: xestream.cxx:415
::std::vector< sal_uInt8 > ScfUInt8Vec
Definition: ftools.hxx:253
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2074
std::size_t Write(const void *pData, std::size_t nBytes)
Writes nBytes bytes from memory.
Definition: xestream.cxx:220
static void GetFormulaTypeAndValue(ScFormulaCell &rCell, const char *&sType, OUString &rValue)
Definition: xestream.cxx:665
static OString ToOString(const Color &rColor)
Definition: xestream.cxx:709
void SetGrammar(const formula::FormulaGrammar::Grammar eGrammar)
Definition: compiler.cxx:228
OUString getString() const
sal_uInt8 mnCharSet
Windows font family.
Definition: xlstyle.hxx:294
ScAddress aStart
Definition: address.hxx:497
Stores global buffers and data needed for Excel export filter.
Definition: xeroot.hxx:59
virtual bool InitCipher(sal_uInt32 nCounter) override
sal_uInt8 GetAlpha() const
const sal_uInt8 EXC_ERR_NA
Definition: xlconst.hxx:110
sal_uInt16 mnCurrSize
Record size written in last record header.
Definition: xestream.hxx:181
bool mbShadow
true = Outlined.
Definition: xlstyle.hxx:299
sal_uInt8 GetRed() const
void SetEncrypter(XclExpEncrypterRef const &xEncrypter)
Definition: xestream.cxx:353
MS Excel binary .xls.
Definition: xlconst.hxx:43
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
virtual bool importDocument() noexcept override
Definition: xestream.cxx:965
SvStream & WriteUInt16(sal_uInt16 nUInt16)
This class is used to export Excel record streams.
Definition: xestream.hxx:72
std::unique_ptr< ScRefreshTimerControl > const & GetRefreshTimerControlAddress() const
Definition: document.hxx:2512
SvStream & WriteInt32(sal_Int32 nInt32)
static void CopyInputToOutput(const css::uno::Reference< css::io::XInputStream > &xInput, const css::uno::Reference< css::io::XOutputStream > &xOutput)
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:785
void Format(OUString &, ScRefFlags nFlags, const ScDocument &, formula::FormulaGrammar::AddressConvention eConv=formula::FormulaGrammar::CONV_OOO, sal_Unicode cDelimiter=0, bool bFullAddressNotation=false) const
Definition: rangelst.cxx:132
virtual OUString SAL_CALL getImplementationName() override
Definition: xestream.cxx:1139
std::shared_ptr< TableStyleList > TableStyleListPtr
sal_uInt16 mnCurrMaxSize
Maximum size of CONTINUE content.
Definition: xestream.hxx:178
static const AllSettings & GetSettings()
virtual bool exportDocument() override
Definition: xestream.cxx:1003
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
SvxEscapement GetScEscapement() const
Returns the Calc escapement style.
Definition: xlstyle.cxx:292
bool HasValidEncrypter() const
Definition: xestream.cxx:358
#define STREAM_SEEK_TO_END
sal_uInt16 mnHeight
Font color.
Definition: xlstyle.hxx:290
sal_uInt64 Seek(sal_uInt64 nPos)
std::shared_ptr< XclExpBiff8Encrypter > XclExpEncrypterRef
Definition: xestream.hxx:47
const sal_uInt16 EXC_ENCR_BLOCKSIZE
Definition: xlstream.hxx:33
ScAddress aEnd
Definition: address.hxx:498
rtl_TextEncoding getBestTextEncodingFromLocale(const css::lang::Locale &rLocale)
XclAddress maLast
Definition: xladdress.hxx:61
sal_uInt32 mnRow
Definition: xladdress.hxx:32
css::uno::Reference< css::io::XOutputStream > openFragmentStream(const OUString &rStreamName, const OUString &rMediaType)
const sal_uInt16 EXC_MAXRECSIZE_BIFF8
Definition: xlstream.hxx:30
void EncryptBytes(SvStream &rStrm,::std::vector< sal_uInt8 > &aBytes)
Definition: xestream.cxx:587
::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:899
sal_uInt16 mnSliceSize
Count of bytes already written in current record.
Definition: xestream.hxx:182
XclAddress maFirst
Definition: xladdress.hxx:60
virtual ~XclExpXmlStream() override
Definition: xestream.cxx:907
RootData & GetOldRoot() const
Returns old RootData struct.
Definition: xlroot.hxx:138
void CreateStringFromTokenArray(OUString &rFormula)
void Encrypt(SvStream &rStrm, sal_uInt8 nData)
Definition: xestream.cxx:495
SfxApplication * SfxGetpApp()
const SCCOL EXC_MAXCOL_XML_2007
Definition: xlconst.hxx:68
sax_fastparser::FSHelperPtr GetStreamForPath(const OUString &rPath)
Definition: xestream.cxx:929
const XclExpRoot * mpRoot
Definition: xestream.hxx:351
Access to global data from other classes.
Definition: xeroot.hxx:112
static css::uno::Sequence< css::beans::NamedValue > GenerateDefaultEncryptionData()
Definition: xeroot.cxx:350
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:856
void WriteExtOptions(ScExtDocOptions &rOpt) const
Definition: viewdata.cxx:3416
LINESTYLE_NONE
const SCROW EXC_MAXROW_XML_2007
Definition: xlconst.hxx:69
const sal_uInt8 EXC_ERR_NUM
Definition: xlconst.hxx:109
MS Excel 4.0.
Definition: xlconst.hxx:34
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:315
const sal_uInt16 EXC_ID_CONT
Definition: xlstream.hxx:36
SvStream & mrStrm
Definition: xestream.hxx:169
SvStream & WriteSChar(signed char nChar)
bool mbOutline
true = Struck out.
Definition: xlstyle.hxx:298
void PushStream(sax_fastparser::FSHelperPtr const &aStream)
Definition: xestream.cxx:918
static sax_fastparser::FSHelperPtr WriteFontData(sax_fastparser::FSHelperPtr pStream, const XclFontData &rFontData, sal_Int32 nNameId)
Definition: xestream.cxx:868
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1137
bool IsAutoCalcShellDisabled() const
Definition: document.hxx:1412
void WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal)
Definition: xestream.cxx:936
SvStream & WriteUInt32(sal_uInt32 nUInt32)
void validateTabNames(std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1144
ScDocShell * getDocShell()
Definition: xestream.cxx:991
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
sal_uInt64 remainingSize()
bool mbItalic
Underline style.
Definition: xlstyle.hxx:296
sax_fastparser::FSHelperPtr & GetCurrentStream()
Definition: xestream.cxx:912
static ScRange lcl_ToRange(const XclRange &rRange)
Definition: xestream.cxx:765
OUString getRelationship(Relationship eRelationship)
sal_uInt8 GetBlue() const
SvNumFormatType GetFormatType() const
void PopStream()
Definition: xestream.cxx:923
void UpdateRecSize()
Rewrites correct record length, if different from calculated.
Definition: xestream.cxx:392
void FlushBuffer()
bool getOutputStream(ProgramOptions const &options, OString const &extension, std::ostream **ppOutputStream, OString &targetSourceFileName, OString &tmpSourceFileName)
sal_uInt16 GetLen() const
const sal_uInt8 EXC_ERR_REF
Definition: xlconst.hxx:107
void SetSliceSize(sal_uInt16 nSize)
Sets data slice length.
Definition: xestream.cxx:134
static const char * lcl_GetErrorString(FormulaError nScErrCode)
Definition: xestream.cxx:649
constexpr OUStringLiteral aData
void Init(const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData)
Definition: xestream.cxx:552
XclExpEncrypterRef mxEncrypter
Definition: xestream.hxx:173
void CreateSaltDigest(const sal_uInt8 nSaltData[16], sal_uInt8 nSaltDigest[16])
static sal_uInt32 GetBlockPos(std::size_t nStrmPos)
Definition: xestream.cxx:577
T * get() const
::sax_fastparser::FSHelperPtr openFragmentStreamWithSerializer(const OUString &rStreamName, const OUString &rMediaType)
sal_uInt16 mnMaxRecSize
Definition: xestream.hxx:176
MS Excel 5.0, MS Excel 7.0 (95)
Definition: xlconst.hxx:35
void restoreTabNames(const std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1220
std::size_t mnPredictSize
Count of bytes already written in current slice.
Definition: xestream.hxx:183
XclExpXmlPathToStateMap maOpenedStreamMap
Definition: xestream.hxx:353
int i
const sal_uInt8 EXC_ERR_VALUE
Definition: xlconst.hxx:106
ScExtDocOptions & GetExtDocOptions() const
Returns the extended document options.
Definition: xlroot.cxx:428
static sal_uInt8 GetXclErrorCode(FormulaError nScError)
Converts a Calc error code to an Excel error code.
Definition: xltools.cxx:201
sax_fastparser::FSHelperPtr CreateOutputStream(const OUString &sFullStream, std::u16string_view sRelativeStream, const css::uno::Reference< css::io::XOutputStream > &xParentRelation, const char *sContentType, std::u16string_view sRelationshipType, OUString *pRelationshipId=nullptr)
Definition: xestream.cxx:941
SfxObjectShell * GetEmbeddedObject() const
Definition: docuno.cxx:448
virtual oox::drawingml::chart::ChartConverter * getChartConverter() override
Definition: xestream.cxx:985
OUString Format(const ScDocument &rDocument, ScRefFlags nFlags=ScRefFlags::ZERO, const ScAddress::Details &rDetails=ScAddress::detailsOOOa1, bool bFullAddressNotation=false) const
Returns string with formatted cell range from aStart to aEnd, according to provided address conventio...
Definition: address.cxx:2170
sal_uInt8 mpnSaltDigest[16]
Definition: xestream.hxx:225
bool Encode(const void *pData, std::size_t nDatLen, sal_uInt8 *pBuffer, std::size_t nBufLen)
A 2D cell range address list with Excel column and row indexes.
Definition: xladdress.hxx:101
std::size_t WriteBytes(const void *pData, std::size_t nSize)
LINESTYLE_SINGLE
float u
void EndRecord()
Checks and corrects real record length.
Definition: xestream.cxx:125
const css::uno::Reference< css::uno::XComponentContext > & getComponentContext() const
const SCTAB EXC_MAXTAB_XML_2007
Definition: xlconst.hxx:70
sal_uInt8 mpnDocId[16]
Crypto algorithm implementation.
Definition: xestream.hxx:223
virtual ::oox::ole::VbaProject * implCreateVbaProject() const override
Definition: xestream.cxx:1134
const ScfUInt16Vec & GetUnicodeBuffer() const
Definition: xestring.hxx:149
sal_uInt16 mnCol
Definition: xladdress.hxx:31
void GetDocId(sal_uInt8 pnDocId[16]) const
Definition: xestream.cxx:489
const sal_uInt8 EXC_STRF_16BIT
Definition: xlstring.hxx:45
A 2D cell address struct with Excel column and row indexes.
Definition: xladdress.hxx:29
XclExpStream & operator<<(sal_Int8 nValue)
Definition: xestream.cxx:140
void CopyFromStream(SvStream &rInStrm, sal_uInt64 nBytes=STREAM_SEEK_TO_END)
Copies nBytes bytes from current position of the stream rInStrm.
Definition: xestream.cxx:288
static ScViewData * GetViewData()
Definition: docsh4.cxx:2592
std::shared_ptr< FastSerializerHelper > FSHelperPtr
static sal_uInt16 GetOffsetInBlock(std::size_t nStrmPos)
Definition: xestream.cxx:582
void WriteByteString(const OString &rString)
Writes string length field and OString buffer.
Definition: xestream.cxx:333
void ReadDoc()
Definition: excdoc.cxx:726
XclExpRoot * pER
Definition: root.hxx:60
const svl::SharedString & GetString()
FormulaError
const css::uno::Reference< css::frame::XModel > & getModel() const
static void lcl_WriteValue(const sax_fastparser::FSHelperPtr &rStream, sal_Int32 nElement, const char *pValue)
Definition: xestream.cxx:835
void SetSvStreamPos(sal_uInt64 nPos)
Sets position of system stream (only allowed outside of records).
Definition: xestream.cxx:373
FormulaTreeNodeRef mpRoot
std::size_t ReadBytes(void *pData, std::size_t nSize)
static OUString GetStreamName(const char *sStreamDir, const char *sStream, sal_Int32 nId)
Definition: xestream.cxx:694
std::stack< sax_fastparser::FSHelperPtr > maStreams
Definition: xestream.hxx:352
const LanguageTag & getLocale()
sal_uInt8 GetGreen() const
const OUString & getFileUrl() const
void * rtlRandomPool
void AppendErrorConstant(OUStringBuffer &rBuffer, FormulaError nError) const
static const char * lcl_GetUnderlineStyle(FontLineStyle eUnderline, bool &bHaveUnderline)
Definition: xestream.cxx:842
std::unique_ptr< char[]> aBuffer
FontLineStyle GetScUnderline() const
Returns the Calc font underline style.
Definition: xlstyle.cxx:279
void WriteZeroBytesToRecord(std::size_t nBytes)
Definition: xestream.cxx:278
void GetSalt(sal_uInt8 pnSalt[16]) const
Definition: xestream.cxx:483
void InitRecord(sal_uInt16 nRecId)
Writes header data, internal setup.
Definition: xestream.cxx:381
::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:89
static ScAddress lcl_ToAddress(const XclAddress &rAddress)
Definition: xestream.cxx:749
bool IsRich() const
Returns true, if the string contains formatting information.
Definition: xestring.hxx:129
unsigned char sal_uInt8
const sal_uInt8 EXC_ERR_NAME
Definition: xlconst.hxx:108
bool VerifyKey(const sal_uInt8 *pSaltData, const sal_uInt8 *pSaltDigest)
sal_uInt8 mnFamily
Escapement type.
Definition: xlstyle.hxx:293
SvStream & WriteFloat(float nFloat)
virtual oox::drawingml::table::TableStyleListPtr getTableStyles() override
Definition: xestream.cxx:980
const css::uno::Reference< css::task::XStatusIndicator > & getStatusIndicator() const
std::size_t mnLastSizePos
Predicted size received from calling function.
Definition: xestream.hxx:186
SvStream & WriteUChar(unsigned char nChar)
void WriteRawZeroBytes(std::size_t nBytes)
Writes a raw sequence of zero bytes.
Definition: xestream.cxx:449
sal_uInt16 mnWeight
Font height in twips (1/20 of a point).
Definition: xlstyle.hxx:291
void UpdateSizeVars(std::size_t nSize)
Recalculates mnCurrSize and mnSliceSize.
Definition: xestream.cxx:401
SvStream & WriteInt16(sal_Int16 nInt16)
const sal_uInt8 EXC_ERR_DIV0
Definition: xlconst.hxx:105
const sal_uInt16 EXC_MAXRECSIZE_BIFF5
Definition: xlstream.hxx:29
css::uno::Sequence< css::beans::NamedValue > GetEncryptionData() const
Definition: xeroot.cxx:333
bool mbExportTemplate
Definition: xestream.hxx:356
sal_uInt64 Tell() const
void * p
void SetAutoCalcShellDisabled(bool bNew)
Definition: document.hxx:1411
const ScDocument & GetDocument() const
Definition: docsh.hxx:220
void WriteCharBuffer(const ScfUInt8Vec &rBuffer)
Writes 8-bit character buffer.
Definition: xestream.cxx:347
XclBiff GetBiff() const
Returns the current BIFF version of the importer/exporter.
Definition: xlroot.hxx:141
sc::FormulaResultValue GetResult()
void DisableEncryption()
Definition: xestream.cxx:368
bool mbValid
Last known stream position.
Definition: xestream.hxx:228
void renameTab(SCTAB aTab, OUString aNewName)
Definition: xestream.cxx:1239
void commitStorage() const
void StartRecord(sal_uInt16 nRecId, std::size_t nRecSize)
Starts a new record: writes header data, stores calculated record size.
Definition: xestream.cxx:113
SvxEscapement
void WriteXml(XclExpXmlStream &)
Definition: excdoc.cxx:805
void exportVBA(SotStorage *pRootStorage)
Reference< XModel > xModel
Color maColor
String with styles (bold, italic).
Definition: xlstyle.hxx:289
sal_uInt64 mnOldPos
Definition: xestream.hxx:227
void EnableEncryption(bool bEnable=true)
Definition: xestream.cxx:363
SvStream & WriteDouble(const double &rDouble)
bool Skip(std::size_t nDatLen)
static const char * lcl_ToVerticalAlignmentRun(SvxEscapement eEscapement, bool &bHaveAlignment)
Definition: xestream.cxx:856
LINESTYLE_DOUBLE
void GetDocId(sal_uInt8 pDocId[16])
bool containsVBAProject()
BiffTyp eDateiTyp
Definition: root.hxx:45
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:310
FontLineStyle
bool mbStrikeout
true = Italic.
Definition: xlstyle.hxx:297
XclExpBiff8Encrypter(const XclExpRoot &rRoot)
Definition: xestream.cxx:462
bool IsIdleEnabled() const
Definition: document.hxx:2201
OUString addRelation(const OUString &rType, std::u16string_view rTarget)
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:215
bool mbValid
Definition: queryiter.cxx:912
A 2D cell range address struct with Excel column and row indexes.
Definition: xladdress.hxx:58
bool mbUseEncrypter
Filter root data.
Definition: xestream.hxx:172
sal_uInt16 nPos
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:261
OUString maName
Definition: xlstyle.hxx:287
bool m_bDetectedRangeSegmentation false
sal_uInt16 PrepareWrite()
Creates CONTINUE record at end of record.
Definition: xestream.cxx:434
ColorAlpha
SfxMedium * GetMedium() const