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