include/oox/ole/vbaexport.hxx | 68 ++++++++++++++ oox/Module_oox.mk | 1 oox/qa/unit/data/vba/reference/simple1.bin |binary oox/qa/unit/data/vba/simple1.bin | 1 oox/qa/unit/vba_compression.cxx | 81 +++++++++++++++++ oox/source/ole/vbaexport.cxx | 134 ++++++++--------------------- 6 files changed, 191 insertions(+), 94 deletions(-)
New commits: commit 442a3b29d9b1fcc4176e7a03a3ae32c1e12de839 Author: Markus Mohrhard <[email protected]> Date: Sat Aug 15 01:25:37 2015 +0200 write compressed stream to a temporary file Change-Id: I4791ec65961129475bb81491dcf681295fcfdea6 diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index 723824b..e2ec045 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -591,10 +591,21 @@ void VbaExport::exportVBA() { // start here with the VBA export const OUString aDirFileName("/tmp/vba_dir_out.bin"); - SvFileStream aDirStream(aDirFileName, StreamMode::WRITE); + SvFileStream aDirStream(aDirFileName, STREAM_READWRITE); // export exportDirStream(aDirStream); + + aDirStream.Seek(0); + + SvMemoryStream aMemoryStream(4096, 4096); + OUString aCompressedFileName("/tmp/vba_dir_out_compressed.bin"); + SvFileStream aCompressedStream(aCompressedFileName, STREAM_READWRITE); + + aMemoryStream.WriteStream(aDirStream); + + VBACompression aCompression(aCompressedStream, aMemoryStream); + aCompression.write(); } css::uno::Reference<css::container::XNameContainer> VbaExport::getBasicLibrary() commit e2dd215f404ea05153f5366c34acc4ecd026432b Author: Markus Mohrhard <[email protected]> Date: Sat Aug 15 01:22:34 2015 +0200 add first vba compression test Change-Id: I9e3abebb0ac932b46f7fc96cd37d39023b783af2 diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx index 146bb88..3217e1b 100644 --- a/include/oox/ole/vbaexport.hxx +++ b/include/oox/ole/vbaexport.hxx @@ -90,7 +90,7 @@ private: sal_uInt16 handleHeader(bool bCompressed); }; -class VBACompression +class OOX_DLLPUBLIC VBACompression { public: VBACompression(SvStream& rCompressedStream, diff --git a/oox/Module_oox.mk b/oox/Module_oox.mk index 361054d..1c8edf0 100644 --- a/oox/Module_oox.mk +++ b/oox/Module_oox.mk @@ -18,6 +18,7 @@ $(eval $(call gb_Module_add_targets,oox,\ $(eval $(call gb_Module_add_check_targets,oox,\ CppunitTest_oox_tokenmap \ + CppunitTest_oox_vba_compression \ )) # vim: set noet sw=4 ts=4: diff --git a/oox/qa/unit/data/vba/reference/simple1.bin b/oox/qa/unit/data/vba/reference/simple1.bin new file mode 100644 index 0000000..bd55e2e Binary files /dev/null and b/oox/qa/unit/data/vba/reference/simple1.bin differ diff --git a/oox/qa/unit/data/vba/simple1.bin b/oox/qa/unit/data/vba/simple1.bin new file mode 100644 index 0000000..61dbbeb --- /dev/null +++ b/oox/qa/unit/data/vba/simple1.bin @@ -0,0 +1 @@ +00000000:0001 0203 0405 0607 0809 1011 1213 . diff --git a/oox/qa/unit/vba_compression.cxx b/oox/qa/unit/vba_compression.cxx new file mode 100644 index 0000000..b526a3c --- /dev/null +++ b/oox/qa/unit/vba_compression.cxx @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <unotest/bootstrapfixturebase.hxx> + +#include <cppunit/plugin/TestPlugIn.h> +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestFixture.h> + +#include <oox/ole/vbaexport.hxx> + +class TestVbaCompression : public test::BootstrapFixtureBase +{ +public: + + void testSimple1(); + + // avoid the BootstrapFixtureBase::setUp and tearDown + virtual void setUp() SAL_OVERRIDE; + virtual void tearDown() SAL_OVERRIDE; + + CPPUNIT_TEST_SUITE(TestVbaCompression); + CPPUNIT_TEST(testSimple1); + CPPUNIT_TEST_SUITE_END(); + +private: +}; + +void TestVbaCompression::testSimple1() +{ + OUString aTestFile = getPathFromSrc("/oox/qa/unit/data/vba/simple1.bin"); + OUString aReference = getPathFromSrc("/oox/qa/unit/data/vba/reference/simple1.bin"); + + SvFileStream aInputStream(aTestFile, StreamMode::READ); + SvMemoryStream aInputMemoryStream(4096, 4096); + aInputMemoryStream.WriteStream(aInputStream); + + SvMemoryStream aOutputMemoryStream(4096, 4096); + VBACompression aCompression(aOutputMemoryStream, aInputMemoryStream); + aCompression.write(); + + SvFileStream aReferenceStream(aReference, StreamMode::READ); + SvMemoryStream aReferenceMemoryStream(4096, 4096); + aReferenceMemoryStream.WriteStream(aReferenceStream); + + aOutputMemoryStream.Seek(0); + SvFileStream aDebugStream("/tmp/vba_debug.bin", StreamMode::WRITE); + aDebugStream.WriteStream(aOutputMemoryStream); + + // CPPUNIT_ASSERT_EQUAL(aReferenceMemoryStream.GetSize(), aOutputMemoryStream.GetSize()); + + const sal_uInt8* pReferenceData = (const sal_uInt8*) aReferenceMemoryStream.GetData(); + const sal_uInt8* pData = (const sal_uInt8*)aOutputMemoryStream.GetData(); + + size_t nSize = std::min(aReferenceMemoryStream.GetSize(), + aOutputMemoryStream.GetSize()); + for (size_t i = 0; i < nSize; ++i) + { + CPPUNIT_ASSERT_EQUAL((int)pReferenceData[i], (int)pData[i]); + } +} + +void TestVbaCompression::setUp() +{ +} + +void TestVbaCompression::tearDown() +{ +} + +CPPUNIT_TEST_SUITE_REGISTRATION(TestVbaCompression); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit f01f290942fd627bdb909c08c7b6a8565c5c03ed Author: Markus Mohrhard <[email protected]> Date: Sat Aug 15 01:20:43 2015 +0200 fix my horrible chunk header code Change-Id: Ic91c06dbe05180d97b0db5de497f26f14b2d4ec4 diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx index 6993fe5..146bb88 100644 --- a/include/oox/ole/vbaexport.hxx +++ b/include/oox/ole/vbaexport.hxx @@ -66,9 +66,6 @@ private: // DecompressedEnd according to the spec sal_uInt64 mnDecompressedEnd; - // Start of the current decompressed chunk - sal_uInt64 mnChunkStart; - void PackCompressedChunkSize(size_t nSize, sal_uInt16& rHeader); void PackCompressedChunkFlag(bool bCompressed, sal_uInt16& rHeader); @@ -89,6 +86,8 @@ private: sal_uInt16& rBitCount, sal_uInt16& rMaximumLength); void writeRawChunk(); + + sal_uInt16 handleHeader(bool bCompressed); }; class VBACompression diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index ea364bc..723824b 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -55,13 +55,27 @@ VBACompressionChunk::VBACompressionChunk(SvStream& rCompressedStream, const sal_ { } +void setUInt16(sal_uInt8* pBuffer, size_t nPos, sal_uInt16 nVal) +{ + pBuffer[nPos] = nVal & 0xFF; + pBuffer[nPos+1] = (nVal & 0xFF00) >> 8; +} + +sal_uInt16 VBACompressionChunk::handleHeader(bool bCompressed) +{ + // handle header bytes + size_t nSize = mnCompressedCurrent; + sal_uInt16 nHeader = 0; + PackCompressedChunkSize(nSize, nHeader); + PackCompressedChunkFlag(bCompressed, nHeader); + PackCompressedChunkSignature(nHeader); + + return nHeader; +} + // section 2.4.1.3.7 void VBACompressionChunk::write() { - mnChunkStart = mrCompressedStream.Tell(); - - // we need to fill these two bytes later - mrCompressedStream.WriteUInt16(0x0); mnDecompressedCurrent = 0; mnCompressedCurrent = 2; @@ -80,30 +94,22 @@ void VBACompressionChunk::write() compressTokenSequence(); } - bool bCompressedFlag = true; if (mnDecompressedCurrent < mnDecompressedEnd) { + sal_uInt64 nChunkStart = mrCompressedStream.Tell(); + mrCompressedStream.WriteUInt16(0); writeRawChunk(); - bCompressedFlag = false; + mrCompressedStream.Seek(nChunkStart); + sal_uInt16 nHeader = handleHeader(false); + mrCompressedStream.WriteUInt16(nHeader); } else { + sal_uInt16 nHeader = handleHeader(true); + setUInt16(pCompressedChunkStream, 0, nHeader); // copy the compressed stream to our output stream mrCompressedStream.Write(pCompressedChunkStream, mnCompressedCurrent); } - - // handle header bytes - size_t nSize = mnCompressedCurrent; - sal_uInt16 nHeader = 0; - PackCompressedChunkSize(nSize, nHeader); - PackCompressedChunkFlag(bCompressedFlag, nHeader); - PackCompressedChunkSignature(nHeader); - - // overwrite the two bytes - sal_uInt64 nEnd = mrCompressedStream.Tell(); - mrCompressedStream.Seek(mnChunkStart); - mrCompressedStream.WriteUInt16(nHeader); - mrCompressedStream.Seek(nEnd); } // section 2.4.1.3.13 @@ -146,12 +152,6 @@ void VBACompressionChunk::compressTokenSequence() mpCompressedChunkStream[nFlagByteIndex] = nFlagByte; } -void setUInt16(sal_uInt8* pBuffer, size_t nPos, sal_uInt16 nVal) -{ - pBuffer[nPos] = nVal & 0xFFFF; - pBuffer[nPos+1] = (nVal & 0xFFFF0000) >> 8; -} - // section 2.4.1.3.9 void VBACompressionChunk::compressToken(size_t index, sal_uInt8& nFlagByte) { commit 1e09c94faacc9746fbfd4a8b9ce01c88aab8a71f Author: Markus Mohrhard <[email protected]> Date: Fri Aug 14 23:48:49 2015 +0200 also write the chunks to the compressed stream Change-Id: I4b079f0f5b83379e1c8c7c7d99a16b794ab36c11 diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index 904fbf9..ea364bc 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -297,6 +297,7 @@ void VBACompression::write() { sal_Size nChunkSize = nRemainingSize > 4096 ? 4096 : nRemainingSize; VBACompressionChunk aChunk(mrCompressedStream, &pData[nSize - nRemainingSize], nChunkSize); + aChunk.write(); // update the uncompressed chunk start marker nRemainingSize -= nChunkSize; commit 31757a223937007220615d2f4f2d41c029d9bb9a Author: Markus Mohrhard <[email protected]> Date: Fri Aug 14 23:47:28 2015 +0200 extract compression methods to make them testable Change-Id: I2ad28134ef723872b9940c02657ee89758efa06f diff --git a/include/oox/ole/vbaexport.hxx b/include/oox/ole/vbaexport.hxx index 88a0561..6993fe5 100644 --- a/include/oox/ole/vbaexport.hxx +++ b/include/oox/ole/vbaexport.hxx @@ -11,6 +11,9 @@ #define __INCLUDED_INCLUDE_OOX_OLE_VBAEXPORT_HXX__ #include <com/sun/star/uno/XInterface.hpp> + +#include <tools/stream.hxx> + #include <oox/dllapi.h> namespace com { namespace sun { namespace star { @@ -35,6 +38,72 @@ private: OUString maProjectName; }; +class VBACompressionChunk +{ +public: + + VBACompressionChunk(SvStream& rCompressedStream, const sal_uInt8* pData, sal_Size nChunkSize); + + void write(); + +private: + SvStream& mrCompressedStream; + const sal_uInt8* mpUncompressedData; + sal_uInt8* mpCompressedChunkStream; + + // same as DecompressedChunkEnd in the spec + sal_Size mnChunkSize; + + // CompressedCurrent according to the spec + sal_uInt64 mnCompressedCurrent; + + // CompressedEnd according to the spec + sal_uInt64 mnCompressedEnd; + + // DecompressedCurrent according to the spec + sal_uInt64 mnDecompressedCurrent; + + // DecompressedEnd according to the spec + sal_uInt64 mnDecompressedEnd; + + // Start of the current decompressed chunk + sal_uInt64 mnChunkStart; + + void PackCompressedChunkSize(size_t nSize, sal_uInt16& rHeader); + + void PackCompressedChunkFlag(bool bCompressed, sal_uInt16& rHeader); + + void PackCompressedChunkSignature(sal_uInt16& rHeader); + + void compressTokenSequence(); + + void compressToken(size_t index, sal_uInt8& nFlagByte); + + void SetFlagBit(size_t index, bool bVal, sal_uInt8& rFlag); + + sal_uInt16 CopyToken(size_t nLength, size_t nOffset); + + void match(size_t& rLength, size_t& rOffset); + + void CopyTokenHelp(sal_uInt16& rLengthMask, sal_uInt16& rOffsetMask, + sal_uInt16& rBitCount, sal_uInt16& rMaximumLength); + + void writeRawChunk(); +}; + +class VBACompression +{ +public: + VBACompression(SvStream& rCompressedStream, + SvMemoryStream& rUncompressedStream); + + void write(); + +private: + SvStream& mrCompressedStream; + SvMemoryStream& mrUncompressedStream; +}; + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index 9d6d52a..904fbf9 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -46,58 +46,7 @@ void exportUTF16String(SvStream& rStrm, const OUString& rString) } } -class VBACompressionChunk -{ -public: - - VBACompressionChunk(SvStream& rCompressedStream, const sal_uInt8* pData, sal_Size nChunkSize); - - void write(); - -private: - SvStream& mrCompressedStream; - const sal_uInt8* mpUncompressedData; - sal_uInt8* mpCompressedChunkStream; - - // same as DecompressedChunkEnd in the spec - sal_Size mnChunkSize; - - // CompressedCurrent according to the spec - sal_uInt64 mnCompressedCurrent; - - // CompressedEnd according to the spec - sal_uInt64 mnCompressedEnd; - - // DecompressedCurrent according to the spec - sal_uInt64 mnDecompressedCurrent; - - // DecompressedEnd according to the spec - sal_uInt64 mnDecompressedEnd; - - // Start of the current decompressed chunk - sal_uInt64 mnChunkStart; - - void PackCompressedChunkSize(size_t nSize, sal_uInt16& rHeader); - - void PackCompressedChunkFlag(bool bCompressed, sal_uInt16& rHeader); - - void PackCompressedChunkSignature(sal_uInt16& rHeader); - - void compressTokenSequence(); - - void compressToken(size_t index, sal_uInt8& nFlagByte); - - void SetFlagBit(size_t index, bool bVal, sal_uInt8& rFlag); - - sal_uInt16 CopyToken(size_t nLength, size_t nOffset); - - void match(size_t& rLength, size_t& rOffset); - - void CopyTokenHelp(sal_uInt16& rLengthMask, sal_uInt16& rOffsetMask, - sal_uInt16& rBitCount, sal_uInt16& rMaximumLength); - - void writeRawChunk(); -}; +} VBACompressionChunk::VBACompressionChunk(SvStream& rCompressedStream, const sal_uInt8* pData, sal_Size nChunkSize): mrCompressedStream(rCompressedStream), @@ -328,19 +277,6 @@ void VBACompressionChunk::writeRawChunk() } } -class VBACompression -{ -public: - VBACompression(SvStream& rCompressedStream, - SvMemoryStream& rUncompressedStream); - - void write(); - -private: - SvStream& mrCompressedStream; - SvMemoryStream& mrUncompressedStream; -}; - VBACompression::VBACompression(SvStream& rCompressedStream, SvMemoryStream& rUncompressedStream): mrCompressedStream(rCompressedStream), @@ -368,8 +304,6 @@ void VBACompression::write() } } -} - VbaExport::VbaExport(css::uno::Reference<css::frame::XModel> xModel): mxModel(xModel) { commit 8c53aa1fb0a056f724092268ce042f723a3368e0 Author: Markus Mohrhard <[email protected]> Date: Fri Aug 14 21:30:36 2015 +0200 fix small glitch Change-Id: I8c219db7aa3eb53c82232469e8334b6a47489cb2 diff --git a/oox/source/ole/vbaexport.cxx b/oox/source/ole/vbaexport.cxx index 93c228f..9d6d52a 100644 --- a/oox/source/ole/vbaexport.cxx +++ b/oox/source/ole/vbaexport.cxx @@ -634,7 +634,7 @@ void writePROJECTMODULES(SvStream& rStrm) rStrm.WriteUInt16(count); // Count writePROJECTCOOKIE(rStrm); writePROJECTMODULE(rStrm, "Module1", "Module1", 0x00000379, "procedure"); - writePROJECTMODULE(rStrm, "ThisWorkbook", "ThisWorkbook", 0x000004BD, "other"); + writePROJECTMODULE(rStrm, "ThisWorkbook", "ThisWorkbook", 0x00000325, "other"); writePROJECTMODULE(rStrm, "Sheet1", "Sheet1", 0x00000325, "other"); writePROJECTMODULE(rStrm, "Sheet2", "Sheet2", 0x00000325, "other"); writePROJECTMODULE(rStrm, "Sheet3", "Sheet3", 0x00000325, "other"); _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
