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>
68#include <formula/grammar.hxx>
69#include <oox/ole/vbaexport.hxx>
70#include <excelvbaproject.hxx>
71
72#include <com/sun/star/task/XStatusIndicator.hpp>
73#include <memory>
76
77#include <externalrefmgr.hxx>
78
79#define DEBUG_XL_ENCRYPTION 0
80
81using ::com::sun::star::uno::XInterface;
82using ::std::vector;
83
84using namespace com::sun::star;
85using namespace ::com::sun::star::beans;
86using namespace ::com::sun::star::io;
87using namespace ::com::sun::star::lang;
88using namespace ::com::sun::star::sheet;
89using namespace ::com::sun::star::uno;
90using namespace ::formula;
91using namespace ::oox;
92
93XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
94 mrStrm( rOutStrm ),
95 mrRoot( rRoot ),
96 mbUseEncrypter( false ),
97 mnMaxRecSize( nMaxRecSize ),
98 mnCurrMaxSize( 0 ),
99 mnMaxSliceSize( 0 ),
100 mnHeaderSize( 0 ),
101 mnCurrSize( 0 ),
102 mnSliceSize( 0 ),
103 mnPredictSize( 0 ),
104 mnLastSizePos( 0 ),
105 mbInRec( false )
106{
107 if( mnMaxRecSize == 0 )
110}
111
113{
115}
116
117void XclExpStream::StartRecord( sal_uInt16 nRecId, std::size_t nRecSize )
118{
119 OSL_ENSURE( !mbInRec, "XclExpStream::StartRecord - another record still open" );
122 mnPredictSize = nRecSize;
123 mbInRec = true;
124 InitRecord( nRecId );
125 SetSliceSize( 0 );
127}
128
130{
131 OSL_ENSURE( mbInRec, "XclExpStream::EndRecord - no record open" );
135 mbInRec = false;
136}
137
138void XclExpStream::SetSliceSize( sal_uInt16 nSize )
139{
140 mnMaxSliceSize = nSize;
141 mnSliceSize = 0;
142}
143
145{
146 PrepareWrite( 1 );
148 mxEncrypter->Encrypt(mrStrm, nValue);
149 else
151 return *this;
152}
153
155{
156 PrepareWrite( 1 );
158 mxEncrypter->Encrypt(mrStrm, nValue);
159 else
161 return *this;
162}
163
165{
166 PrepareWrite( 2 );
168 mxEncrypter->Encrypt(mrStrm, nValue);
169 else
171 return *this;
172}
173
175{
176 PrepareWrite( 2 );
178 mxEncrypter->Encrypt(mrStrm, nValue);
179 else
181 return *this;
182}
183
185{
186 PrepareWrite( 4 );
188 mxEncrypter->Encrypt(mrStrm, nValue);
189 else
191 return *this;
192}
193
195{
196 PrepareWrite( 4 );
198 mxEncrypter->Encrypt(mrStrm, nValue);
199 else
201 return *this;
202}
203
205{
206 PrepareWrite( 4 );
208 mxEncrypter->Encrypt(mrStrm, fValue);
209 else
210 mrStrm.WriteFloat( fValue );
211 return *this;
212}
213
215{
216 PrepareWrite( 8 );
218 mxEncrypter->Encrypt(mrStrm, fValue);
219 else
220 mrStrm.WriteDouble( fValue );
221 return *this;
222}
223
224std::size_t XclExpStream::Write( const void* pData, std::size_t nBytes )
225{
226 std::size_t nRet = 0;
227 if( pData && (nBytes > 0) )
228 {
229 if( mbInRec )
230 {
231 const sal_uInt8* pBuffer = static_cast< const sal_uInt8* >( pData );
232 std::size_t nBytesLeft = nBytes;
233 bool bValid = true;
234
235 while( bValid && (nBytesLeft > 0) )
236 {
237 std::size_t nWriteLen = ::std::min< std::size_t >( PrepareWrite(), nBytesLeft );
238 std::size_t nWriteRet = nWriteLen;
240 {
241 OSL_ENSURE(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
242 vector<sal_uInt8> aBytes(nWriteLen);
243 memcpy(aBytes.data(), pBuffer, nWriteLen);
244 mxEncrypter->EncryptBytes(mrStrm, aBytes);
245 // TODO: How do I check if all the bytes have been successfully written ?
246 }
247 else
248 {
249 nWriteRet = mrStrm.WriteBytes(pBuffer, nWriteLen);
250 bValid = (nWriteLen == nWriteRet);
251 OSL_ENSURE( bValid, "XclExpStream::Write - stream write error" );
252 }
253 pBuffer += nWriteRet;
254 nRet += nWriteRet;
255 nBytesLeft -= nWriteRet;
256 UpdateSizeVars( nWriteRet );
257 }
258 }
259 else
260 nRet = mrStrm.WriteBytes(pData, nBytes);
261 }
262 return nRet;
263}
264
265void XclExpStream::WriteZeroBytes( std::size_t nBytes )
266{
267 if( mbInRec )
268 {
269 std::size_t nBytesLeft = nBytes;
270 while( nBytesLeft > 0 )
271 {
272 std::size_t nWriteLen = ::std::min< std::size_t >( PrepareWrite(), nBytesLeft );
273 WriteRawZeroBytes( nWriteLen );
274 nBytesLeft -= nWriteLen;
275 UpdateSizeVars( nWriteLen );
276 }
277 }
278 else
279 WriteRawZeroBytes( nBytes );
280}
281
282void XclExpStream::WriteZeroBytesToRecord( std::size_t nBytes )
283{
284 if (!mbInRec)
285 // not in record.
286 return;
287
288 for (std::size_t i = 0; i < nBytes; ++i)
289 *this << sal_uInt8(0)/*nZero*/;
290}
291
292void XclExpStream::CopyFromStream(SvStream& rInStrm, sal_uInt64 const nBytes)
293{
294 sal_uInt64 const nRemaining(rInStrm.remainingSize());
295 sal_uInt64 nBytesLeft = ::std::min(nBytes, nRemaining);
296 if( nBytesLeft <= 0 )
297 return;
298
299 const std::size_t nMaxBuffer = 4096;
300 std::unique_ptr<sal_uInt8[]> pBuffer(
301 new sal_uInt8[ ::std::min<std::size_t>(nBytesLeft, nMaxBuffer) ]);
302 bool bValid = true;
303
304 while( bValid && (nBytesLeft > 0) )
305 {
306 std::size_t nWriteLen = ::std::min<std::size_t>(nBytesLeft, nMaxBuffer);
307 rInStrm.ReadBytes(pBuffer.get(), nWriteLen);
308 std::size_t nWriteRet = Write( pBuffer.get(), nWriteLen );
309 bValid = (nWriteLen == nWriteRet);
310 nBytesLeft -= nWriteRet;
311 }
312}
313
315{
316 SetSliceSize( 0 );
317 nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
318 sal_uInt16 nCharLen = nFlags ? 2 : 1;
319
320 for( const auto& rItem : rBuffer )
321 {
322 if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
323 {
325 operator<<( nFlags );
326 }
327 if( nCharLen == 2 )
328 operator<<( rItem );
329 else
330 operator<<( static_cast< sal_uInt8 >( rItem ) );
331 }
332}
333
334// Xcl has an obscure sense of whether starting a new record or not,
335// and crashes if it encounters the string header at the very end of a record.
336// Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
337void XclExpStream::WriteByteString( const OString& rString )
338{
339 SetSliceSize( 0 );
340 std::size_t nLen = ::std::min< std::size_t >( rString.getLength(), 0x00FF );
341 nLen = ::std::min< std::size_t >( nLen, 0xFF );
342
343 sal_uInt16 nLeft = PrepareWrite();
344 if( mbInRec && (nLeft <= 1) )
346
347 operator<<( static_cast< sal_uInt8 >( nLen ) );
348 Write( rString.getStr(), nLen );
349}
350
352{
353 SetSliceSize( 0 );
354 Write( rBuffer.data(), rBuffer.size() );
355}
356
358{
359 mxEncrypter = xEncrypter;
360}
361
363{
364 return mxEncrypter && mxEncrypter->IsValid();
365}
366
368{
369 mbUseEncrypter = bEnable && HasValidEncrypter();
370}
371
373{
374 EnableEncryption(false);
375}
376
377void XclExpStream::SetSvStreamPos(sal_uInt64 const nPos)
378{
379 OSL_ENSURE( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
380 mbInRec ? 0 : mrStrm.Seek( nPos );
381}
382
383// private --------------------------------------------------------------------
384
385void XclExpStream::InitRecord( sal_uInt16 nRecId )
386{
388 mrStrm.WriteUInt16( nRecId );
389
391 mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< std::size_t >( mnPredictSize, mnCurrMaxSize ) );
394}
395
397{
398 if( mnCurrSize != mnHeaderSize )
399 {
402 }
403}
404
405void XclExpStream::UpdateSizeVars( std::size_t nSize )
406{
407 OSL_ENSURE( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
408 mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
409
410 if( mnMaxSliceSize > 0 )
411 {
412 OSL_ENSURE( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
413 mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
415 mnSliceSize = 0;
416 }
417}
418
420{
425}
426
427void XclExpStream::PrepareWrite( sal_uInt16 nSize )
428{
429 if( mbInRec )
430 {
431 if( (mnCurrSize + nSize > mnCurrMaxSize) ||
434 UpdateSizeVars( nSize );
435 }
436}
437
439{
440 sal_uInt16 nRet = 0;
441 if( mbInRec )
442 {
443 if( (mnCurrSize >= mnCurrMaxSize) ||
446 UpdateSizeVars( 0 );
447
449 }
450 return nRet;
451}
452
453void XclExpStream::WriteRawZeroBytes( std::size_t nBytes )
454{
455 const sal_uInt32 nData = 0;
456 std::size_t nBytesLeft = nBytes;
457 while( nBytesLeft >= sizeof( nData ) )
458 {
459 mrStrm.WriteUInt32( nData );
460 nBytesLeft -= sizeof( nData );
461 }
462 if( nBytesLeft )
463 mrStrm.WriteBytes(&nData, nBytesLeft);
464}
465
467 mnOldPos(STREAM_SEEK_TO_END),
468 mbValid(false)
469{
470 Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData();
471 if( !aEncryptionData.hasElements() )
472 // Empty password. Get the default biff8 password.
474 Init( aEncryptionData );
475}
476
478{
479}
480
481void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const
482{
483 if ( sizeof( mpnSaltDigest ) == 16 )
484 memcpy( pnSaltDigest, mpnSaltDigest, 16 );
485}
486
488{
489 if ( sizeof( mpnSalt ) == 16 )
490 memcpy( pnSalt, mpnSalt, 16 );
491}
492
494{
495 if ( sizeof( mpnDocId ) == 16 )
496 memcpy( pnDocId, mpnDocId, 16 );
497}
498
500{
501 vector<sal_uInt8> aByte { nData };
502 EncryptBytes(rStrm, aByte);
503}
504
505void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
506{
507 ::std::vector<sal_uInt8> pnBytes
508 {
509 o3tl::narrowing<sal_uInt8>(nData & 0xFF),
510 o3tl::narrowing<sal_uInt8>((nData >> 8) & 0xFF)
511 };
512 EncryptBytes(rStrm, pnBytes);
513}
514
515void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
516{
517 ::std::vector<sal_uInt8> pnBytes
518 {
519 o3tl::narrowing<sal_uInt8>(nData & 0xFF),
520 o3tl::narrowing<sal_uInt8>((nData >> 8) & 0xFF),
521 o3tl::narrowing<sal_uInt8>((nData >> 16) & 0xFF),
522 o3tl::narrowing<sal_uInt8>((nData >> 24) & 0xFF)
523 };
524 EncryptBytes(rStrm, pnBytes);
525}
526
527void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
528{
529 ::std::vector<sal_uInt8> pnBytes(4);
530 memcpy(pnBytes.data(), &fValue, 4);
531 EncryptBytes(rStrm, pnBytes);
532}
533
534void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
535{
536 ::std::vector<sal_uInt8> pnBytes(8);
537 memcpy(pnBytes.data(), &fValue, 8);
538 EncryptBytes(rStrm, pnBytes);
539}
540
542{
543 Encrypt(rStrm, static_cast<sal_uInt8>(nData));
544}
545
546void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
547{
548 Encrypt(rStrm, static_cast<sal_uInt16>(nData));
549}
550
551void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
552{
553 Encrypt(rStrm, static_cast<sal_uInt32>(nData));
554}
555
556void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
557{
558 mbValid = false;
559
560 if( !maCodec.InitCodec( rEncryptionData ) )
561 return;
562
564
565 // generate the salt here
566 rtlRandomPool aRandomPool = rtl_random_createPool ();
567 rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
568 rtl_random_destroyPool( aRandomPool );
569
570 memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
571
572 // generate salt hash.
574 aCodec.InitCodec( rEncryptionData );
576
577 // verify to make sure it's in good shape.
579}
580
581sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( std::size_t nStrmPos )
582{
583 return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
584}
585
586sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( std::size_t nStrmPos )
587{
588 return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
589}
590
591void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
592{
593 sal_uInt64 nStrmPos = rStrm.Tell();
594 sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
595 sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
596
597 SAL_INFO("sc.filter", "XclExpBiff8Encrypter::EncryptBytes: stream pos = "
598 << nStrmPos << " offset in block = " << nBlockOffset
599 << " block pos = " << nBlockPos);
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 const char* lcl_GetUnderlineStyle( FontLineStyle eUnderline, bool& bHaveUnderline )
839{
840 bHaveUnderline = true;
841 switch( eUnderline )
842 {
843 // OOXTODO: doubleAccounting, singleAccounting
844 // OOXTODO: what should be done with the other FontLineStyle values?
845 case LINESTYLE_SINGLE: return "single";
846 case LINESTYLE_DOUBLE: return "double";
847 case LINESTYLE_NONE:
848 default: bHaveUnderline = false; return "none";
849 }
850}
851
852static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
853{
854 bHaveAlignment = true;
855 switch( eEscapement )
856 {
857 case SvxEscapement::Superscript: return "superscript";
858 case SvxEscapement::Subscript: return "subscript";
859 case SvxEscapement::Off:
860 default: bHaveAlignment = false; return "baseline";
861 }
862}
863
865{
866 bool bHaveUnderline, bHaveVertAlign;
867 const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
868 const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
869
870 if (rFontData.mnWeight > 400)
871 pStream->singleElement(XML_b, XML_val, ToPsz( true ));
872 if (rFontData.mbItalic)
873 pStream->singleElement(XML_i, XML_val, ToPsz( true ));
874 if (rFontData.mbStrikeout)
875 pStream->singleElement(XML_strike, XML_val, ToPsz( true ));
876 // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
877 // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
878 if (rFontData.mbOutline)
879 pStream->singleElement(XML_outline, XML_val, ToPsz( true ));
880 if (rFontData.mbShadow)
881 pStream->singleElement(XML_shadow, XML_val, ToPsz( true ));
882 if (bHaveUnderline)
883 pStream->singleElement(XML_u, XML_val, pUnderline);
884 if (bHaveVertAlign)
885 pStream->singleElement(XML_vertAlign, XML_val, pVertAlign);
886 pStream->singleElement(XML_sz, XML_val, OString::number( rFontData.mnHeight / 20.0 )); // Twips->Pt
887
888 auto& rComplexColor = rFontData.maComplexColor;
889 if (rComplexColor.isValidSchemeType())
890 {
891 sal_Int32 nTheme = oox::convertThemeColorTypeToExcelThemeNumber(rComplexColor.getSchemeType());
892 double fTintShade = oox::convertColorTransformsToTintOrShade(rComplexColor);
893 pStream->singleElement(XML_color,
894 XML_theme, OString::number(nTheme),
895 XML_tint, sax_fastparser::UseIf(OString::number(fTintShade), fTintShade != 0.0));
896 }
897 else if (rComplexColor.getFinalColor() != Color( ColorAlpha, 0, 0xFF, 0xFF, 0xFF))
898 {
899 pStream->singleElement(XML_color,
900 XML_rgb, XclXmlUtils::ToOString(rComplexColor.getFinalColor()));
901 }
902 pStream->singleElement(nFontId, XML_val, rFontData.maName);
903 pStream->singleElement(XML_family, XML_val, OString::number( rFontData.mnFamily ));
904 if (rFontData.mnCharSet != 0)
905 pStream->singleElement(XML_charset, XML_val, OString::number(rFontData.mnCharSet));
906
907 return pStream;
908}
909
910XclExpXmlStream::XclExpXmlStream( const uno::Reference< XComponentContext >& rCC, bool bExportVBA, bool bExportTemplate )
911 : XmlFilterBase( rCC ),
912 mpRoot( nullptr ),
913 mbExportVBA(bExportVBA),
914 mbExportTemplate(bExportTemplate)
915{
916}
917
919{
920 assert(maStreams.empty() && "Forgotten PopStream()?");
921}
922
924{
925 OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
926 return maStreams.top();
927}
928
930{
931 maStreams.push( aStream );
932}
933
935{
936 OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
937 maStreams.pop();
938}
939
941{
942 if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
944 return maOpenedStreamMap[ sPath ].second;
945}
946
947void XclExpXmlStream::WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal)
948{
949 GetCurrentStream()->write(" ")->writeId(nAttr)->write("=\"")->writeEscaped(sVal)->write("\"");
950}
951
953 const OUString& sFullStream,
954 std::u16string_view sRelativeStream,
955 const uno::Reference< XOutputStream >& xParentRelation,
956 const char* sContentType,
957 std::u16string_view sRelationshipType,
958 OUString* pRelationshipId )
959{
960 OUString sRelationshipId;
961 if (xParentRelation.is())
962 sRelationshipId = addRelation( xParentRelation, OUString(sRelationshipType), sRelativeStream );
963 else
964 sRelationshipId = addRelation( OUString(sRelationshipType), sRelativeStream );
965
966 if( pRelationshipId )
967 *pRelationshipId = sRelationshipId;
968
969 sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
970
971 maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
972
973 return p;
974}
975
977{
978 return false;
979}
980
982{
983 return nullptr;
984}
985
987{
988 return nullptr;
989}
990
992{
994}
995
997{
998 // DO NOT CALL
999 return nullptr;
1000}
1001
1003{
1004 uno::Reference< XInterface > xModel( getModel(), UNO_QUERY );
1005
1006 ScModelObj *pObj = comphelper::getFromUnoTunnel < ScModelObj >( xModel );
1007
1008 if ( pObj )
1009 return static_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
1010
1011 return nullptr;
1012}
1013
1015{
1016 ScDocShell* pShell = getDocShell();
1017 ScDocument& rDoc = pShell->GetDocument();
1019
1020 const bool bValidateTabNames = officecfg::Office::Calc::Filter::Export::MS_Excel::TruncateLongSheetNames::get();
1021 std::vector<OUString> aOriginalTabNames;
1022 if (bValidateTabNames)
1023 {
1024 validateTabNames(aOriginalTabNames);
1025 }
1026
1027 uno::Reference<task::XStatusIndicator> xStatusIndicator = getStatusIndicator();
1028
1029 if (xStatusIndicator.is())
1030 xStatusIndicator->start(ScResId(STR_SAVE_DOC), 100);
1031
1032 // NOTE: Don't use SotStorage or SvStream any more, and never call
1033 // SfxMedium::GetOutStream() anywhere in the xlsx export filter code!
1034 // Instead, write via XOutputStream instance.
1035 tools::SvRef<SotStorage> rStorage = static_cast<SotStorage*>(nullptr);
1036 drawingml::DrawingML::ResetMlCounters();
1037
1038 auto& rGraphicExportCache = drawingml::GraphicExportCache::get();
1039
1040 rGraphicExportCache.push();
1041
1043 EXC_BIFF8, *pShell->GetMedium (), rStorage, rDoc,
1046 aData.meOutput = EXC_OUTPUT_XML_2007;
1048 aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
1049 aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
1050 aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
1051 aData.mpCompileFormulaCxt = std::make_shared<sc::CompileFormulaContext>(rDoc);
1052 // set target path to get correct relative links to target document, not source
1053 INetURLObject aPath(getFileUrl());
1054 aData.maBasePath = OUString("file:///" + aPath.GetPath() + "\\").replace('\\', '/')
1055 // fix for Linux
1056 .replaceFirst("file:////", "file:///");
1057
1058 XclExpRoot aRoot( aData );
1059
1060 mpRoot = &aRoot;
1061 aRoot.GetOldRoot().pER = &aRoot;
1062 aRoot.GetOldRoot().eDateiTyp = Biff8;
1063 // Get the viewsettings before processing
1064 if (ScViewData* pViewData = ScDocShell::GetViewData())
1065 pViewData->WriteExtOptions( mpRoot->GetExtDocOptions() );
1066 else
1067 {
1068 // Try to get ScViewData through the current ScDocShell
1069 ScTabViewShell* pTabViewShell = pShell->GetBestViewShell( false );
1070 if ( pTabViewShell )
1071 {
1072 pViewData = &pTabViewShell->GetViewData();
1073 pViewData->WriteExtOptions( mpRoot->GetExtDocOptions() );
1074 }
1075 }
1076
1077 static constexpr OUStringLiteral workbook = u"xl/workbook.xml";
1078 const char* pWorkbookContentType = nullptr;
1079 if (mbExportVBA)
1080 {
1081 if (mbExportTemplate)
1082 {
1083 pWorkbookContentType = "application/vnd.ms-excel.template.macroEnabled.main+xml";
1084 }
1085 else
1086 {
1087 pWorkbookContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml";
1088 }
1089 }
1090 else
1091 {
1092 if (mbExportTemplate)
1093 {
1094 pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml";
1095 }
1096 else
1097 {
1098 pWorkbookContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml";
1099 }
1100 }
1101
1102 PushStream( CreateOutputStream( workbook, workbook,
1103 uno::Reference <XOutputStream>(),
1104 pWorkbookContentType,
1105 oox::getRelationship(Relationship::OFFICEDOCUMENT) ) );
1106
1107 if (mbExportVBA)
1108 {
1109 VbaExport aExport(getModel());
1110 if (aExport.containsVBAProject())
1111 {
1112 SvMemoryStream aVbaStream(4096, 4096);
1113 tools::SvRef<SotStorage> pVBAStorage(new SotStorage(aVbaStream));
1114 aExport.exportVBA( pVBAStorage.get() );
1115 aVbaStream.Seek(0);
1116 css::uno::Reference<css::io::XInputStream> xVBAStream(
1117 new utl::OInputStreamWrapper(aVbaStream));
1118 css::uno::Reference<css::io::XOutputStream> xVBAOutput =
1119 openFragmentStream("xl/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1120 comphelper::OStorageHelper::CopyInputToOutput(xVBAStream, xVBAOutput);
1121
1122 addRelation(GetCurrentStream()->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), u"vbaProject.bin");
1123 }
1124 }
1125
1126 // destruct at the end of the block
1127 {
1128 ExcDocument aDocRoot( aRoot );
1129 if (xStatusIndicator.is())
1130 xStatusIndicator->setValue(10);
1131 aDocRoot.ReadDoc();
1132 if (xStatusIndicator.is())
1133 xStatusIndicator->setValue(40);
1134 aDocRoot.WriteXml( *this );
1136 }
1137
1138 PopStream();
1139 // Free all FSHelperPtr, to flush data before committing storage
1140 for (auto& entry : maOpenedStreamMap)
1141 {
1142 if (!entry.second.second)
1143 continue;
1144 entry.second.second->endDocument();
1145 }
1146 maOpenedStreamMap.clear();
1147
1148 commitStorage();
1149
1150 if (bValidateTabNames)
1151 {
1152 restoreTabNames(aOriginalTabNames);
1153 }
1154
1155 if (xStatusIndicator.is())
1156 xStatusIndicator->end();
1157 mpRoot = nullptr;
1158
1159 rGraphicExportCache.pop();
1160
1161 return true;
1162}
1163
1165{
1166 return new ::oox::xls::ExcelVbaProject( getComponentContext(), uno::Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
1167}
1168
1170{
1171 return "TODO";
1172}
1173
1174void XclExpXmlStream::validateTabNames(std::vector<OUString>& aOriginalTabNames)
1175{
1176 const int MAX_TAB_NAME_LENGTH = 31;
1177
1178 ScDocShell* pShell = getDocShell();
1179 ScDocument& rDoc = pShell->GetDocument();
1180
1181 // get original names
1182 aOriginalTabNames.resize(rDoc.GetTableCount());
1183 for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1184 {
1185 rDoc.GetName(nTab, aOriginalTabNames[nTab]);
1186 }
1187
1188 // new tab names
1189 std::vector<OUString> aNewTabNames;
1190 aNewTabNames.reserve(rDoc.GetTableCount());
1191
1192 // check and rename
1193 for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1194 {
1195 const OUString& rOriginalName = aOriginalTabNames[nTab];
1196 if (rOriginalName.getLength() > MAX_TAB_NAME_LENGTH)
1197 {
1198 OUString aNewName;
1199
1200 // let's try just truncate "<first 31 chars>"
1201 if (aNewName.isEmpty())
1202 {
1203 aNewName = rOriginalName.copy(0, MAX_TAB_NAME_LENGTH);
1204 if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
1205 aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
1206 {
1207 // was found => let's use another tab name
1208 aNewName.clear();
1209 }
1210 }
1211
1212 // let's try "<first N chars>-XXX" template
1213 for (int digits=1; digits<10 && aNewName.isEmpty(); digits++)
1214 {
1215 const int rangeStart = pow(10, digits - 1);
1216 const int rangeEnd = pow(10, digits);
1217
1218 for (int i=rangeStart; i<rangeEnd && aNewName.isEmpty(); i++)
1219 {
1220 aNewName = OUString::Concat(rOriginalName.subView(0, MAX_TAB_NAME_LENGTH - 1 - digits)) + "-" + OUString::number(i);
1221 if (aNewTabNames.end() != std::find(aNewTabNames.begin(), aNewTabNames.end(), aNewName) ||
1222 aOriginalTabNames.end() != std::find(aOriginalTabNames.begin(), aOriginalTabNames.end(), aNewName))
1223 {
1224 // was found => let's use another tab name
1225 aNewName.clear();
1226 }
1227 }
1228 }
1229
1230 if (!aNewName.isEmpty())
1231 {
1232 // new name was created => rename
1233 renameTab(nTab, aNewName);
1234 aNewTabNames.push_back(aNewName);
1235 }
1236 else
1237 {
1238 // default: do not rename
1239 aNewTabNames.push_back(rOriginalName);
1240 }
1241 }
1242 else
1243 {
1244 // default: do not rename
1245 aNewTabNames.push_back(rOriginalName);
1246 }
1247 }
1248}
1249
1250void XclExpXmlStream::restoreTabNames(const std::vector<OUString>& aOriginalTabNames)
1251{
1252 ScDocShell* pShell = getDocShell();
1253 ScDocument& rDoc = pShell->GetDocument();
1254
1255 for (SCTAB nTab=0; nTab < rDoc.GetTableCount(); nTab++)
1256 {
1257 const OUString& rOriginalName = aOriginalTabNames[nTab];
1258
1259 OUString rModifiedName;
1260 rDoc.GetName(nTab, rModifiedName);
1261
1262 if (rOriginalName != rModifiedName)
1263 {
1264 renameTab(nTab, rOriginalName);
1265 }
1266 }
1267}
1268
1269void XclExpXmlStream::renameTab(SCTAB aTab, OUString aNewName)
1270{
1271 ScDocShell* pShell = getDocShell();
1272 ScDocument& rDoc = pShell->GetDocument();
1273
1274 bool bAutoCalcShellDisabled = rDoc.IsAutoCalcShellDisabled();
1275 bool bIdleEnabled = rDoc.IsIdleEnabled();
1276
1277 rDoc.SetAutoCalcShellDisabled( true );
1278 rDoc.EnableIdle(false);
1279
1280 if (rDoc.RenameTab(aTab, aNewName))
1281 {
1282 SfxGetpApp()->Broadcast(SfxHint(SfxHintId::ScTablesChanged));
1283 }
1284
1285 rDoc.SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
1286 rDoc.EnableIdle(bIdleEnabled);
1287}
1288
1289/* 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:809
void ReadDoc()
Definition: excdoc.cxx:730
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:219
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2623
static ScViewData * GetViewData()
Definition: docsh4.cxx:2607
bool IsIdleEnabled() const
Definition: document.hxx:2207
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:837
std::unique_ptr< ScRefreshTimerControl > const & GetRefreshTimerControlAddress() const
Definition: document.hxx:2522
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
void EnableIdle(bool bDo)
Definition: document.hxx:2208
void SetAutoCalcShellDisabled(bool bNew)
Definition: document.hxx:1415
bool IsAutoCalcShellDisabled() const
Definition: document.hxx:1416
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:204
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:297
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:344
void WriteExtOptions(ScExtDocOptions &rOpt) const
Definition: viewdata.cxx:3427
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:581
XclExpBiff8Encrypter(const XclExpRoot &rRoot)
Definition: xestream.cxx:466
void Encrypt(SvStream &rStrm, sal_uInt8 nData)
Definition: xestream.cxx:499
void GetSaltDigest(sal_uInt8 pnSaltDigest[16]) const
Definition: xestream.cxx:481
void Init(const css::uno::Sequence< css::beans::NamedValue > &aEncryptionData)
Definition: xestream.cxx:556
void GetSalt(sal_uInt8 pnSalt[16]) const
Definition: xestream.cxx:487
::msfilter::MSCodec_Std97 maCodec
Definition: xestream.hxx:222
void GetDocId(sal_uInt8 pnDocId[16]) const
Definition: xestream.cxx:493
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:586
sal_uInt8 mpnDocId[16]
Crypto algorithm implementation.
Definition: xestream.hxx:223
void EncryptBytes(SvStream &rStrm, ::std::vector< sal_uInt8 > &aBytes)
Definition: xestream.cxx:591
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:419
void UpdateRecSize()
Rewrites correct record length, if different from calculated.
Definition: xestream.cxx:396
XclExpStream(SvStream &rOutStrm, const XclExpRoot &rRoot, sal_uInt16 nMaxRecSize=0)
Constructs the Excel record export stream.
Definition: xestream.cxx:93
void InitRecord(sal_uInt16 nRecId)
Writes header data, internal setup.
Definition: xestream.cxx:385
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:351
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:453
void WriteZeroBytes(std::size_t nBytes)
Writes a sequence of nBytes zero bytes (respects slice setting).
Definition: xestream.cxx:265
void DisableEncryption()
Definition: xestream.cxx:372
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:282
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:314
bool mbUseEncrypter
Filter root data.
Definition: xestream.hxx:172
sal_uInt16 PrepareWrite()
Creates CONTINUE record at end of record.
Definition: xestream.cxx:438
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:292
sal_uInt16 mnMaxRecSize
Definition: xestream.hxx:176
void EnableEncryption(bool bEnable=true)
Definition: xestream.cxx:367
void SetEncrypter(XclExpEncrypterRef const &xEncrypter)
Definition: xestream.cxx:357
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:138
void UpdateSizeVars(std::size_t nSize)
Recalculates mnCurrSize and mnSliceSize.
Definition: xestream.cxx:405
bool HasValidEncrypter() const
Definition: xestream.cxx:362
void StartRecord(sal_uInt16 nRecId, std::size_t nRecSize)
Starts a new record: writes header data, stores calculated record size.
Definition: xestream.cxx:117
SvStream & mrStrm
Definition: xestream.hxx:169
void WriteByteString(const OString &rString)
Writes string length field and OString buffer.
Definition: xestream.cxx:337
std::size_t Write(const void *pData, std::size_t nBytes)
Writes nBytes bytes from memory.
Definition: xestream.cxx:224
XclExpStream & operator<<(sal_Int8 nValue)
Definition: xestream.cxx:144
void SetSvStreamPos(sal_uInt64 nPos)
Sets position of system stream (only allowed outside of records).
Definition: xestream.cxx:377
void EndRecord()
Checks and corrects real record length.
Definition: xestream.cxx:129
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:940
ScDocShell * getDocShell()
Definition: xestream.cxx:1002
virtual ::oox::ole::VbaProject * implCreateVbaProject() const override
Definition: xestream.cxx:1164
virtual oox::vml::Drawing * getVmlDrawing() override
Definition: xestream.cxx:981
void WriteAttribute(sal_Int32 nAttr, std::u16string_view sVal)
Definition: xestream.cxx:947
void validateTabNames(std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1174
const XclExpRoot * mpRoot
Definition: xestream.hxx:351
virtual oox::drawingml::table::TableStyleListPtr getTableStyles() override
Definition: xestream.cxx:991
virtual const oox::drawingml::Theme * getCurrentTheme() const override
Definition: xestream.cxx:986
sax_fastparser::FSHelperPtr & GetCurrentStream()
Definition: xestream.cxx:923
bool mbExportTemplate
Definition: xestream.hxx:356
void renameTab(SCTAB aTab, OUString aNewName)
Definition: xestream.cxx:1269
std::stack< sax_fastparser::FSHelperPtr > maStreams
Definition: xestream.hxx:352
virtual bool importDocument() noexcept override
Definition: xestream.cxx:976
XclExpXmlPathToStateMap maOpenedStreamMap
Definition: xestream.hxx:353
virtual oox::drawingml::chart::ChartConverter * getChartConverter() override
Definition: xestream.cxx:996
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:952
void PopStream()
Definition: xestream.cxx:934
virtual bool exportDocument() override
Definition: xestream.cxx:1014
void PushStream(sax_fastparser::FSHelperPtr const &aStream)
Definition: xestream.cxx:929
virtual ~XclExpXmlStream() override
Definition: xestream.cxx:918
XclExpXmlStream(const css::uno::Reference< css::uno::XComponentContext > &rCC, bool bExportVBA, bool bExportTemplate)
Definition: xestream.cxx:910
virtual OUString SAL_CALL getImplementationName() override
Definition: xestream.cxx:1169
void restoreTabNames(const std::vector< OUString > &aOriginalTabNames)
Definition: xestream.cxx:1250
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:864
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
#define SAL_INFO(area, stream)
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)
static double convertColorTransformsToTintOrShade(model::ComplexColor const &rComplexColor)
static sal_Int32 convertThemeColorTypeToExcelThemeNumber(model::ThemeColorType eType)
const char * UseIf(const char *s, bool bUse)
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:923
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:285
sal_uInt8 mnCharSet
Windows font family.
Definition: xlstyle.hxx:292
sal_uInt16 mnHeight
String with styles (bold, italic).
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:278
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
model::ComplexColor maComplexColor
true = Shadowed.
Definition: xlstyle.hxx:299
SvxEscapement GetScEscapement() const
Returns the Calc escapement style.
Definition: xlstyle.cxx:291
OUString maName
Definition: xlstyle.hxx:286
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:852
static ScAddress lcl_ToAddress(const XclAddress &rAddress)
Definition: xestream.cxx:752
static const char * lcl_GetUnderlineStyle(FontLineStyle eUnderline, bool &bHaveUnderline)
Definition: xestream.cxx:838
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