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