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