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