summaryrefslogtreecommitdiffstats
path: root/writerperfect/qa/unit/WPXSvStreamTest.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'writerperfect/qa/unit/WPXSvStreamTest.cxx')
-rw-r--r--writerperfect/qa/unit/WPXSvStreamTest.cxx355
1 files changed, 355 insertions, 0 deletions
diff --git a/writerperfect/qa/unit/WPXSvStreamTest.cxx b/writerperfect/qa/unit/WPXSvStreamTest.cxx
new file mode 100644
index 000000000..0bd7b7b15
--- /dev/null
+++ b/writerperfect/qa/unit/WPXSvStreamTest.cxx
@@ -0,0 +1,355 @@
+/* -*- 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 <algorithm>
+#include <cassert>
+#include <sstream>
+
+#include <memory>
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/seqstream.hxx>
+
+#include <test/bootstrapfixture.hxx>
+
+#include <WPXSvInputStream.hxx>
+
+namespace io = com::sun::star::io;
+namespace ucb = com::sun::star::ucb;
+namespace uno = com::sun::star::uno;
+
+using std::shared_ptr;
+using std::unique_ptr;
+
+using librevenge::RVNGInputStream;
+using librevenge::RVNG_SEEK_CUR;
+using librevenge::RVNG_SEEK_END;
+using librevenge::RVNG_SEEK_SET;
+
+using std::equal;
+
+using writerperfect::WPXSvInputStream;
+
+namespace
+{
+class WPXSvStreamTest : public test::BootstrapFixture
+{
+public:
+ CPPUNIT_TEST_SUITE(WPXSvStreamTest);
+ CPPUNIT_TEST(testRead);
+ CPPUNIT_TEST(testSeekSet);
+ CPPUNIT_TEST(testSeekCur);
+ CPPUNIT_TEST(testSeekEnd);
+ CPPUNIT_TEST(testStructured);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void testRead();
+ void testSeekSet();
+ void testSeekCur();
+ void testSeekEnd();
+ void testStructured();
+};
+
+const char aText[] = "hello world";
+constexpr OUStringLiteral aOLEFile = u"/writerperfect/qa/unit/data/stream/fdo40686-1.doc";
+constexpr OUStringLiteral aZipFile = u"/writerperfect/qa/unit/data/stream/test.odt";
+
+shared_ptr<RVNGInputStream> lcl_createStream()
+{
+ using comphelper::SequenceInputStream;
+
+ const css::uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8*>(aText),
+ sizeof aText);
+ const uno::Reference<io::XInputStream> xInputStream(new SequenceInputStream(aData));
+
+ shared_ptr<RVNGInputStream> pInputStream;
+ if (xInputStream.is())
+ pInputStream = std::make_shared<WPXSvInputStream>(xInputStream);
+
+ return pInputStream;
+}
+
+shared_ptr<RVNGInputStream> lcl_createStreamForURL(const OUString& rURL)
+{
+ using uno::Reference;
+ using uno::UNO_QUERY_THROW;
+
+ const Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext(),
+ css::uno::UNO_SET_THROW);
+ const Reference<ucb::XSimpleFileAccess> xFileAccess(
+ xContext->getServiceManager()->createInstanceWithContext(
+ "com.sun.star.ucb.SimpleFileAccess", xContext),
+ UNO_QUERY_THROW);
+ const Reference<io::XInputStream> xInputStream(xFileAccess->openFileRead(rURL),
+ css::uno::UNO_SET_THROW);
+
+ return std::make_shared<WPXSvInputStream>(xInputStream);
+}
+
+void lcl_testSubStreams(const shared_ptr<RVNGInputStream>& pInput)
+{
+ shared_ptr<RVNGInputStream> pSubStream;
+
+ // all valid substreams can be read
+ for (std::size_t i = 0; i != pInput->subStreamCount(); ++i)
+ {
+ std::ostringstream msg("opening substream ");
+ msg << i;
+ pSubStream.reset(pInput->getSubStreamById(i));
+ CPPUNIT_ASSERT_MESSAGE(msg.str(), bool(pSubStream));
+ }
+
+ // invalid substreams cannot be read
+ pSubStream.reset(pInput->getSubStreamById(pInput->subStreamCount()));
+ CPPUNIT_ASSERT(!pSubStream);
+}
+
+void WPXSvStreamTest::testRead()
+{
+ const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
+ const unsigned long nLen = sizeof aText;
+
+ unsigned long nReadBytes = 0;
+ const unsigned char* pData = nullptr;
+ const unsigned char* const pTextOrig = reinterpret_cast<const unsigned char*>(aText);
+ const unsigned char* pText = pTextOrig;
+
+ // reading by small pieces
+ pData = pInput->read(1UL, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(1UL, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(!pInput->isEnd());
+ pText += nReadBytes;
+
+ pData = pInput->read(2UL, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(2UL, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(!pInput->isEnd());
+ pText += nReadBytes;
+
+ pData = pInput->read(3UL, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(3UL, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(!pInput->isEnd());
+ pText += nReadBytes;
+
+ assert(nLen > 6);
+ pData = pInput->read(nLen - 6, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(nLen - 6, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ // reading everything at once
+ pInput->seek(0, RVNG_SEEK_SET);
+ pText = pTextOrig;
+
+ pData = pInput->read(nLen, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(nLen, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ // trying to read too much
+ pInput->seek(0, RVNG_SEEK_SET);
+ pText = pTextOrig;
+
+ pData = pInput->read(nLen + 1, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(nLen, nReadBytes);
+ CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ // trying to read nothing
+ pInput->seek(0, RVNG_SEEK_SET);
+ pData = pInput->read(0UL, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(0UL, nReadBytes);
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT_EQUAL(pData, static_cast<const unsigned char*>(nullptr));
+ CPPUNIT_ASSERT(!pInput->isEnd());
+}
+
+void WPXSvStreamTest::testSeekSet()
+{
+ const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
+ const long nLen = sizeof aText;
+
+ // check initial state
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ // valid seeks
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(1, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(1L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(nLen, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(nLen, pInput->tell());
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ // go back to the beginning
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+
+ // invalid seeks
+ CPPUNIT_ASSERT(0 != pInput->seek(-1, RVNG_SEEK_SET));
+ // Okay, this is not defined. But it is what the WPXSvInputStream
+ // does ATM and it is reasonable.
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT(0 != pInput->seek(nLen + 1, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(nLen, pInput->tell());
+ CPPUNIT_ASSERT(pInput->isEnd());
+}
+
+void WPXSvStreamTest::testSeekCur()
+{
+ const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
+ const long nLen = sizeof aText;
+
+ // check initial state
+ CPPUNIT_ASSERT(!pInput->isEnd());
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+
+ // valid seeks
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_CUR));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(1, RVNG_SEEK_CUR));
+ CPPUNIT_ASSERT_EQUAL(1L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-1, RVNG_SEEK_CUR));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ // go back to the beginning
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+
+ // invalid seeks
+ CPPUNIT_ASSERT(0 != pInput->seek(-1, RVNG_SEEK_CUR));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT(0 != pInput->seek(nLen + 1, RVNG_SEEK_CUR));
+ CPPUNIT_ASSERT_EQUAL(nLen, pInput->tell());
+ CPPUNIT_ASSERT(pInput->isEnd());
+}
+
+void WPXSvStreamTest::testSeekEnd()
+{
+ const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
+ const long nLen = sizeof aText;
+
+ // check initial state
+ CPPUNIT_ASSERT(!pInput->isEnd());
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+
+ // valid seeks
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_END));
+ CPPUNIT_ASSERT_EQUAL(nLen, pInput->tell());
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-1, RVNG_SEEK_END));
+ CPPUNIT_ASSERT_EQUAL(nLen - 1, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-nLen, RVNG_SEEK_END));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+
+ // go back to the beginning
+ CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+
+ // invalid seeks
+ CPPUNIT_ASSERT(0 != pInput->seek(1, RVNG_SEEK_END));
+ CPPUNIT_ASSERT_EQUAL(nLen, pInput->tell());
+ CPPUNIT_ASSERT(pInput->isEnd());
+
+ CPPUNIT_ASSERT(0 != pInput->seek(-nLen - 1, RVNG_SEEK_END));
+ CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
+ CPPUNIT_ASSERT(!pInput->isEnd());
+}
+
+void WPXSvStreamTest::testStructured()
+{
+ // OLE2
+ {
+ const shared_ptr<RVNGInputStream> pInput(
+ lcl_createStreamForURL(m_directories.getURLFromSrc(aOLEFile)));
+ assert(bool(pInput));
+
+ CPPUNIT_ASSERT(pInput->isStructured());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned>(2), pInput->subStreamCount());
+ lcl_testSubStreams(pInput);
+
+ // check for existing substream
+ CPPUNIT_ASSERT(pInput->existsSubStream("WordDocument"));
+ unique_ptr<RVNGInputStream> pSubStream(pInput->getSubStreamByName("WordDocument"));
+ CPPUNIT_ASSERT(bool(pSubStream));
+ CPPUNIT_ASSERT(!pSubStream->isEnd());
+
+ // check for not existing substream
+ CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
+ pSubStream.reset(pInput->getSubStreamByName("foo"));
+ CPPUNIT_ASSERT(!pSubStream);
+ }
+
+ // Zip
+ {
+ const shared_ptr<RVNGInputStream> pInput(
+ lcl_createStreamForURL(m_directories.getURLFromSrc(aZipFile)));
+ assert(bool(pInput));
+
+ CPPUNIT_ASSERT(pInput->isStructured());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned>(9), pInput->subStreamCount());
+ lcl_testSubStreams(pInput);
+
+ // check for existing substream
+ CPPUNIT_ASSERT(pInput->existsSubStream("content.xml"));
+ unique_ptr<RVNGInputStream> pSubStream(pInput->getSubStreamByName("content.xml"));
+ CPPUNIT_ASSERT(bool(pSubStream));
+ CPPUNIT_ASSERT(!pSubStream->isEnd());
+
+ // check for not existing substream
+ CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
+ pSubStream.reset(pInput->getSubStreamByName("foo"));
+ CPPUNIT_ASSERT(!pSubStream);
+ }
+
+ // not structured
+ {
+ const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
+
+ CPPUNIT_ASSERT(!pInput->isStructured());
+ CPPUNIT_ASSERT_EQUAL(static_cast<unsigned>(0), pInput->subStreamCount());
+ CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
+ CPPUNIT_ASSERT(!pInput->getSubStreamByName("foo"));
+ CPPUNIT_ASSERT(!pInput->getSubStreamById(42));
+ CPPUNIT_ASSERT(!pInput->subStreamName(42));
+ }
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(WPXSvStreamTest);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */