[Libreoffice-commits] core.git: offapi/com package/qa package/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue Jan 17 02:06:17 UTC 2017


 offapi/com/sun/star/packages/zip/ZipFileAccess.idl |    8 +
 package/qa/cppunit/data/a2z.zip                    |binary
 package/qa/cppunit/test_package.cxx                |   89 +++++++++++++++++++++
 package/source/zippackage/zipfileaccess.cxx        |   32 +++++++
 4 files changed, 127 insertions(+), 2 deletions(-)

New commits:
commit 294f2e627cc6f1d0483f7affcf96467a4bd3ba5a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Jan 16 15:33:37 2017 -0500

    tdf#97597: attempt to add test for multithreaded input stream buffering.
    
    But it always passes, even when UseBufferedStream is set to false...
    Needs improvement.
    
    Change-Id: I98f65dcd7bec3b47a437fdc6cc42c6e8e3775522
    Reviewed-on: https://gerrit.libreoffice.org/33190
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>

diff --git a/offapi/com/sun/star/packages/zip/ZipFileAccess.idl b/offapi/com/sun/star/packages/zip/ZipFileAccess.idl
index 6d54509..7677c94 100644
--- a/offapi/com/sun/star/packages/zip/ZipFileAccess.idl
+++ b/offapi/com/sun/star/packages/zip/ZipFileAccess.idl
@@ -23,7 +23,7 @@
 #include <com/sun/star/packages/zip/ZipException.idl>
 #include <com/sun/star/ucb/ContentCreationException.idl>
 #include <com/sun/star/ucb/InteractiveIOException.idl>
-
+#include <com/sun/star/beans/NamedValue.idl>
 
 
 module com {  module sun {  module star {   module packages {  module zip {
@@ -38,6 +38,12 @@ service ZipFileAccess : XZipFileAccess2
                  com::sun::star::ucb::ContentCreationException,
                  com::sun::star::ucb::InteractiveIOException,
                  com::sun::star::packages::zip::ZipException );
+
+    createWithArguments( [in] sequence<com::sun::star::beans::NamedValue> args )
+        raises ( com::sun::star::io::IOException,
+                 com::sun::star::ucb::ContentCreationException,
+                 com::sun::star::ucb::InteractiveIOException,
+                 com::sun::star::packages::zip::ZipException );
 };
 
 
diff --git a/package/qa/cppunit/data/a2z.zip b/package/qa/cppunit/data/a2z.zip
new file mode 100644
index 0000000..4a04508
Binary files /dev/null and b/package/qa/cppunit/data/a2z.zip differ
diff --git a/package/qa/cppunit/test_package.cxx b/package/qa/cppunit/test_package.cxx
index 07b3abb..80f02d8e 100644
--- a/package/qa/cppunit/test_package.cxx
+++ b/package/qa/cppunit/test_package.cxx
@@ -10,8 +10,11 @@
 #include <comphelper/processfactory.hxx>
 #include <unotest/filters-test.hxx>
 #include <unotest/bootstrapfixturebase.hxx>
+#include <comphelper/threadpool.hxx>
 #include "com/sun/star/packages/zip/ZipFileAccess.hpp"
 
+#include <iterator>
+
 using namespace ::com::sun::star;
 
 namespace
@@ -28,9 +31,11 @@ namespace
             SfxFilterFlags, SotClipboardFormatId, unsigned int) override;
 
         void test();
+        void testThreadedStreams();
 
         CPPUNIT_TEST_SUITE(PackageTest);
         CPPUNIT_TEST(test);
+        CPPUNIT_TEST(testThreadedStreams);
         CPPUNIT_TEST_SUITE_END();
     };
 
@@ -56,6 +61,90 @@ namespace
             m_directories.getURLFromSrc("/package/qa/cppunit/data/"));
     }
 
+    // TODO : This test currently doesn't fail even when you set
+    // UseBufferedStream to false. Look into this and replace it with a better
+    // test that actually fails when the aforementioned flag is set to false.
+    void PackageTest::testThreadedStreams()
+    {
+        class Worker : public comphelper::ThreadTask
+        {
+            uno::Reference<io::XInputStream> mxStrm;
+            std::vector<char>& mrBuf;
+
+        public:
+            Worker(
+                const std::shared_ptr<comphelper::ThreadTaskTag>& pTag,
+                const uno::Reference<io::XInputStream>& xStrm,
+                std::vector<char>& rBuf ) :
+                comphelper::ThreadTask(pTag), mxStrm(xStrm), mrBuf(rBuf) {}
+
+            virtual void doWork() override
+            {
+                sal_Int32 nSize = mxStrm->available();
+
+                uno::Sequence<sal_Int8> aBytes;
+                while (nSize > 0)
+                {
+                    sal_Int32 nBytesRead = mxStrm->readBytes(aBytes, 4096);
+                    const sal_Int8* p = aBytes.getArray();
+                    const sal_Int8* pEnd = p + nBytesRead;
+                    std::copy(p, pEnd, std::back_inserter(mrBuf));
+                    nSize -= nBytesRead;
+                }
+            }
+        };
+
+        OUString aURL = m_directories.getURLFromSrc("/package/qa/cppunit/data/a2z.zip");
+
+        uno::Sequence<beans::NamedValue> aArgs(2);
+        aArgs[0].Name = "URL";
+        aArgs[0].Value <<= aURL;
+        aArgs[1].Name = "UseBufferedStream";
+        aArgs[1].Value <<= true;
+
+        uno::Reference<packages::zip::XZipFileAccess2> xZip(
+            packages::zip::ZipFileAccess::createWithArguments(comphelper::getProcessComponentContext(), aArgs));
+
+        CPPUNIT_ASSERT(xZip.is());
+
+        uno::Reference<container::XNameAccess> xNA(xZip, uno::UNO_QUERY);
+        CPPUNIT_ASSERT(xNA.is());
+
+        {
+            comphelper::ThreadPool aPool(4);
+            std::shared_ptr<comphelper::ThreadTaskTag> pTag = comphelper::ThreadPool::createThreadTaskTag();
+
+            std::vector<std::vector<char>> aTestBuffers(26);
+            auto itBuf = aTestBuffers.begin();
+
+            for (char c = 'a'; c <= 'z'; ++c, ++itBuf)
+            {
+                OUString aName(c);
+                aName += ".txt";
+
+                uno::Reference<io::XInputStream> xStrm;
+                xNA->getByName(aName) >>= xStrm;
+
+                CPPUNIT_ASSERT(xStrm.is());
+                aPool.pushTask(new Worker(pTag, xStrm, *itBuf));
+            }
+
+            aPool.waitUntilDone(pTag);
+
+            // Verify the streams.
+            CPPUNIT_ASSERT_EQUAL(size_t(26), aTestBuffers.size());
+            itBuf = aTestBuffers.begin();
+
+            for (char c = 'a'; c <= 'z'; ++c, ++itBuf)
+            {
+                const std::vector<char>& rBuf = *itBuf;
+                CPPUNIT_ASSERT_EQUAL(size_t(1048576), rBuf.size()); // 1 MB each.
+                for (char check : rBuf)
+                    CPPUNIT_ASSERT_EQUAL(c, check);
+            }
+        }
+    }
+
     CPPUNIT_TEST_SUITE_REGISTRATION(PackageTest);
 }
 
diff --git a/package/source/zippackage/zipfileaccess.cxx b/package/source/zippackage/zipfileaccess.cxx
index 88ac19c..b6875ee 100644
--- a/package/source/zippackage/zipfileaccess.cxx
+++ b/package/source/zippackage/zipfileaccess.cxx
@@ -23,6 +23,7 @@
 #include <com/sun/star/io/XActiveDataSink.hpp>
 #include <com/sun/star/io/XStream.hpp>
 #include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
 #include <comphelper/processfactory.hxx>
 #include <cppuhelper/supportsservice.hxx>
 #include <zipfileaccess.hxx>
@@ -182,8 +183,11 @@ void SAL_CALL OZipFileAccess::initialize( const uno::Sequence< uno::Any >& aArgu
     OUString aParamURL;
     uno::Reference< io::XStream > xStream;
     uno::Reference< io::XSeekable > xSeekable;
+    uno::Sequence<beans::NamedValue> aArgs;
 
-    if ( ( aArguments[0] >>= aParamURL ) )
+    bool bUseBufferedStream = false;
+
+    auto openInputStream = [&]()
     {
         ::ucbhelper::Content aContent(
             aParamURL,
@@ -196,6 +200,11 @@ void SAL_CALL OZipFileAccess::initialize( const uno::Sequence< uno::Any >& aArgu
             m_bOwnContent = true;
             xSeekable.set( m_xContentStream, uno::UNO_QUERY );
         }
+    };
+
+    if ( ( aArguments[0] >>= aParamURL ) )
+    {
+        openInputStream();
     }
     else if ( (aArguments[0] >>= xStream ) )
     {
@@ -207,6 +216,25 @@ void SAL_CALL OZipFileAccess::initialize( const uno::Sequence< uno::Any >& aArgu
     {
         xSeekable.set( m_xContentStream, uno::UNO_QUERY );
     }
+    else if (aArguments[0] >>= aArgs)
+    {
+        for (sal_Int32 i = 0; i < aArgs.getLength(); ++i)
+        {
+            const beans::NamedValue& rArg = aArgs[i];
+
+            if (rArg.Name == "URL")
+                rArg.Value >>= aParamURL;
+            else if (rArg.Name == "UseBufferedStream")
+                rArg.Value >>= bUseBufferedStream;
+        }
+
+        if (aParamURL.isEmpty())
+            throw lang::IllegalArgumentException(
+                THROW_WHERE"required argument 'URL' is not given or invalid.",
+                uno::Reference<uno::XInterface>(), 1);
+
+        openInputStream();
+    }
     else
         throw lang::IllegalArgumentException(THROW_WHERE, uno::Reference< uno::XInterface >(), 1 );
 
@@ -224,6 +252,8 @@ void SAL_CALL OZipFileAccess::initialize( const uno::Sequence< uno::Any >& aArgu
                 m_xContentStream,
                 m_xContext,
                 true );
+
+    m_pZipFile->setUseBufferedStream(bUseBufferedStream);
 }
 
 // XNameAccess


More information about the Libreoffice-commits mailing list