1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <comphelper/processfactory.hxx>
11 #include <unotest/filters-test.hxx>
12 #include <unotest/bootstrapfixturebase.hxx>
13 #include <comphelper/threadpool.hxx>
14 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
15 #include <com/sun/star/beans/NamedValue.hpp>
19 using namespace ::com::sun::star
;
24 : public test::FiltersTest
25 , public test::BootstrapFixtureBase
30 virtual void setUp() override
;
32 virtual bool load(const OUString
&,
33 const OUString
&rURL
, const OUString
&,
34 SfxFilterFlags
, SotClipboardFormatId
, unsigned int) override
;
37 void testThreadedStreams();
38 void testBufferedThreadedStreams();
41 CPPUNIT_TEST_SUITE(PackageTest
);
43 CPPUNIT_TEST(testThreadedStreams
);
44 CPPUNIT_TEST(testBufferedThreadedStreams
);
45 CPPUNIT_TEST(testZip64
);
46 CPPUNIT_TEST_SUITE_END();
49 uno::Reference
<container::XNameAccess
> mxNA
;
50 void verifyStreams( std::vector
<std::vector
<char>> &aBuffers
);
53 void PackageTest::setUp()
55 BootstrapFixtureBase::setUp();
56 OUString aURL
= m_directories
.getURLFromSrc(u
"/package/qa/cppunit/data/a2z.zip");
58 uno::Sequence
<beans::NamedValue
> aNVs
{ { u
"URL"_ustr
, uno::Any(aURL
) } };
59 uno::Sequence
<uno::Any
> aArgs
{ uno::Any(aNVs
) };
61 uno::Reference
<uno::XComponentContext
> xCxt
= comphelper::getProcessComponentContext();
62 uno::Reference
<lang::XMultiComponentFactory
> xSvcMgr
= xCxt
->getServiceManager();
64 uno::Reference
<packages::zip::XZipFileAccess2
> xZip(
65 xSvcMgr
->createInstanceWithArgumentsAndContext(
66 u
"com.sun.star.packages.zip.ZipFileAccess"_ustr
, aArgs
, xCxt
),
69 CPPUNIT_ASSERT(xZip
.is());
72 CPPUNIT_ASSERT(mxNA
.is());
75 bool PackageTest::load(const OUString
&,
76 const OUString
&rURL
, const OUString
&,
77 SfxFilterFlags
, SotClipboardFormatId
, unsigned int)
81 uno::Reference
<css::packages::zip::XZipFileAccess2
> xZip(
82 css::packages::zip::ZipFileAccess::createWithURL(comphelper::getProcessComponentContext(), rURL
));
91 void PackageTest::test()
94 m_directories
.getURLFromSrc(u
"/package/qa/cppunit/data/"));
97 void PackageTest::verifyStreams( std::vector
<std::vector
<char>> &aBuffers
)
99 CPPUNIT_ASSERT_EQUAL(size_t(26), aBuffers
.size());
100 auto itBuf
= aBuffers
.begin();
102 for (char c
= 'a'; c
<= 'z'; ++c
, ++itBuf
)
104 const std::vector
<char>& rBuf
= *itBuf
;
105 CPPUNIT_ASSERT_EQUAL(size_t(1048576), rBuf
.size()); // 1 MB each.
106 for (char check
: rBuf
)
108 CPPUNIT_ASSERT_MESSAGE("stream does not contain expected data", false);
112 // TODO : This test currently doesn't fail even when you set
113 // UseBufferedStream to false. Look into this and replace it with a better
114 // test that actually fails when the aforementioned flag is set to false.
115 void PackageTest::testThreadedStreams()
117 class Worker
: public comphelper::ThreadTask
119 uno::Reference
<io::XInputStream
> mxStrm
;
120 std::vector
<char>& mrBuf
;
124 const std::shared_ptr
<comphelper::ThreadTaskTag
>& pTag
,
125 const uno::Reference
<io::XInputStream
>& xStrm
,
126 std::vector
<char>& rBuf
) :
127 comphelper::ThreadTask(pTag
), mxStrm(xStrm
), mrBuf(rBuf
) {}
129 virtual void doWork() override
131 sal_Int32 nSize
= mxStrm
->available();
133 uno::Sequence
<sal_Int8
> aBytes
;
136 sal_Int32 nBytesRead
= mxStrm
->readBytes(aBytes
, 4096);
137 const sal_Int8
* p
= aBytes
.getArray();
138 const sal_Int8
* pEnd
= p
+ nBytesRead
;
139 std::copy(p
, pEnd
, std::back_inserter(mrBuf
));
146 comphelper::ThreadPool
aPool(4);
147 std::shared_ptr
<comphelper::ThreadTaskTag
> pTag
= comphelper::ThreadPool::createThreadTaskTag();
149 std::vector
<std::vector
<char>> aTestBuffers(26);
150 auto itBuf
= aTestBuffers
.begin();
152 for (char c
= 'a'; c
<= 'z'; ++c
, ++itBuf
)
154 OUString aName
= OUStringChar(c
) + ".txt";
156 uno::Reference
<io::XInputStream
> xStrm
;
157 mxNA
->getByName(aName
) >>= xStrm
;
159 CPPUNIT_ASSERT(xStrm
.is());
160 aPool
.pushTask(std::make_unique
<Worker
>(pTag
, xStrm
, *itBuf
));
163 aPool
.waitUntilDone(pTag
);
164 verifyStreams( aTestBuffers
);
168 void PackageTest::testBufferedThreadedStreams()
170 std::vector
<std::vector
<char>> aTestBuffers(26);
171 auto itBuf
= aTestBuffers
.begin();
172 sal_Int32 nReadSize
= 0;
174 for (char c
= 'a'; c
<= 'z'; ++c
, ++itBuf
)
176 itBuf
->reserve(1024*1024);
177 OUString aName
= OUStringChar(c
) + ".txt";
179 uno::Reference
<io::XInputStream
> xStrm
;
180 //Size of each stream is 1mb (>10000) => XBufferedThreadedStream
181 mxNA
->getByName(aName
) >>= xStrm
;
183 CPPUNIT_ASSERT(xStrm
.is());
184 sal_Int32 nSize
= xStrm
->available();
186 uno::Sequence
<sal_Int8
> aBytes
;
187 //Read chunks of increasing size
192 sal_Int32 nBytesRead
= xStrm
->readBytes(aBytes
, nReadSize
);
193 const sal_Int8
* p
= aBytes
.getArray();
194 const sal_Int8
* pEnd
= p
+ nBytesRead
;
195 std::copy(p
, pEnd
, std::back_inserter(*itBuf
));
200 verifyStreams( aTestBuffers
);
203 void PackageTest::testZip64()
205 // This small zip file have 2 files (content.xml, styles.xml) that have
206 // Zip64 Extended Information Extra Field in both
207 // "Local file header" and "Central directory file header",
208 // and have ZIP64 format "Data descriptor".
209 OUString aURL2
= m_directories
.getURLFromSrc(u
"/package/qa/cppunit/data/export64.zip");
211 uno::Sequence
<beans::NamedValue
> aNVs2
{ { u
"URL"_ustr
, uno::Any(aURL2
) } };
212 uno::Sequence
<uno::Any
> aArgs2
{ uno::Any(aNVs2
) };
214 uno::Reference
<uno::XComponentContext
> xCxt
= comphelper::getProcessComponentContext();
215 uno::Reference
<lang::XMultiComponentFactory
> xSvcMgr
= xCxt
->getServiceManager();
217 // Without Zip64 support, it would crash here
218 uno::Reference
<packages::zip::XZipFileAccess2
> xZip2(
219 xSvcMgr
->createInstanceWithArgumentsAndContext(
220 u
"com.sun.star.packages.zip.ZipFileAccess"_ustr
, aArgs2
, xCxt
),
223 CPPUNIT_ASSERT(xZip2
.is());
225 uno::Reference
<container::XNameAccess
> xNA
;
227 CPPUNIT_ASSERT(xNA
.is());
229 // Check if the styles.xml seems to be right
230 uno::Reference
<io::XInputStream
> xStrm
;
231 xNA
->getByName(u
"styles.xml"_ustr
) >>= xStrm
;
232 CPPUNIT_ASSERT(xStrm
.is());
234 sal_Int32 nSize
= xStrm
->available();
235 CPPUNIT_ASSERT_EQUAL(sal_Int32(1112), nSize
);
237 uno::Sequence
<sal_Int8
> aBytes
;
238 sal_Int32 nBytesRead
= xStrm
->readBytes(aBytes
, nSize
);
239 const sal_Int8
* p
= aBytes
.getArray();
240 CPPUNIT_ASSERT_EQUAL(sal_Int32(1112), nBytesRead
);
242 // Check the uncompressed styles.xml file content.
243 OString
aFile(static_cast<const char*>(static_cast<const void*>(p
)), nSize
);
244 CPPUNIT_ASSERT(aFile
.startsWith(
245 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<office:document-styles"));
246 CPPUNIT_ASSERT(aFile
.endsWith(
247 "</number:time-style>\r\n </office:styles>\r\n</office:document-styles>\r\n"));
250 CPPUNIT_TEST_SUITE_REGISTRATION(PackageTest
);
253 CPPUNIT_PLUGIN_IMPLEMENT();
255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */