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