Line data Source code
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 :
10 : #include <algorithm>
11 : #include <cassert>
12 : #include <sstream>
13 :
14 : #include <boost/shared_ptr.hpp>
15 :
16 : #include <cppunit/extensions/HelperMacros.h>
17 :
18 : #include "com/sun/star/io/XInputStream.hpp"
19 : #include "com/sun/star/ucb/XSimpleFileAccess.hpp"
20 : #include "com/sun/star/uno/Reference.hxx"
21 :
22 : #include "comphelper/processfactory.hxx"
23 : #include "comphelper/seqstream.hxx"
24 :
25 : #include "rtl/ref.hxx"
26 :
27 : #include "test/bootstrapfixture.hxx"
28 :
29 : #include <writerperfect/WPXSvInputStream.hxx>
30 :
31 : namespace io = com::sun::star::io;
32 : namespace ucb = com::sun::star::ucb;
33 : namespace uno = com::sun::star::uno;
34 :
35 : using boost::shared_ptr;
36 :
37 : using librevenge::RVNGInputStream;
38 : using librevenge::RVNG_SEEK_CUR;
39 : using librevenge::RVNG_SEEK_END;
40 : using librevenge::RVNG_SEEK_SET;
41 :
42 : using std::equal;
43 :
44 : using writerperfect::WPXSvInputStream;
45 :
46 : namespace
47 : {
48 :
49 30 : class WPXSvStreamTest : public test::BootstrapFixture
50 : {
51 : public:
52 4 : CPPUNIT_TEST_SUITE(WPXSvStreamTest);
53 2 : CPPUNIT_TEST(testRead);
54 2 : CPPUNIT_TEST(testSeekSet);
55 2 : CPPUNIT_TEST(testSeekCur);
56 2 : CPPUNIT_TEST(testSeekEnd);
57 2 : CPPUNIT_TEST(testStructured);
58 4 : CPPUNIT_TEST_SUITE_END();
59 :
60 : private:
61 : void testRead();
62 : void testSeekSet();
63 : void testSeekCur();
64 : void testSeekEnd();
65 : void testStructured();
66 : };
67 :
68 : static const char aText[] = "hello world";
69 : static const char aOLEFile[] = "/writerperfect/qa/unit/data/stream/fdo40686-1.doc";
70 : static const char aZipFile[] = "/writerperfect/qa/unit/data/stream/test.odt";
71 :
72 10 : shared_ptr<RVNGInputStream> lcl_createStream()
73 : {
74 : using comphelper::SequenceInputStream;
75 :
76 10 : const css::uno::Sequence<sal_Int8> aData(reinterpret_cast<const sal_Int8 *>(aText), sizeof aText);
77 20 : const uno::Reference<io::XInputStream> xInputStream(new SequenceInputStream(aData));
78 :
79 10 : shared_ptr<RVNGInputStream> pInputStream;
80 10 : if (xInputStream.is())
81 10 : pInputStream.reset(new WPXSvInputStream(xInputStream));
82 :
83 20 : return pInputStream;
84 : }
85 :
86 4 : const shared_ptr<RVNGInputStream> lcl_createStreamForURL(const rtl::OUString &rURL)
87 : {
88 : using uno::Reference;
89 : using uno::UNO_QUERY_THROW;
90 :
91 4 : const Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext(), UNO_QUERY_THROW);
92 : const Reference<ucb::XSimpleFileAccess> xFileAccess(
93 8 : xContext->getServiceManager()->createInstanceWithContext("com.sun.star.ucb.SimpleFileAccess", xContext),
94 8 : UNO_QUERY_THROW);
95 8 : const Reference<io::XInputStream> xInputStream(xFileAccess->openFileRead(rURL), UNO_QUERY_THROW);
96 :
97 4 : const shared_ptr<RVNGInputStream> pInput(new WPXSvInputStream(xInputStream));
98 8 : return pInput;
99 : }
100 :
101 4 : void lcl_testSubStreams(const shared_ptr<RVNGInputStream> &pInput)
102 : {
103 4 : shared_ptr<RVNGInputStream> pSubStream;
104 :
105 : // all valid substreams can be read
106 26 : for (std::size_t i = 0; i != pInput->subStreamCount(); ++i)
107 : {
108 22 : std::ostringstream msg("opening substream ");
109 22 : msg << i;
110 22 : pSubStream.reset(pInput->getSubStreamById(i));
111 22 : CPPUNIT_ASSERT_MESSAGE(msg.str(), bool(pSubStream));
112 22 : }
113 :
114 : // invalid substreams cannot be read
115 4 : pSubStream.reset(pInput->getSubStreamById(pInput->subStreamCount()));
116 4 : CPPUNIT_ASSERT(!pSubStream);
117 4 : }
118 :
119 2 : void WPXSvStreamTest::testRead()
120 : {
121 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
122 2 : const unsigned long nLen = sizeof aText;
123 :
124 2 : unsigned long nReadBytes = 0;
125 2 : const unsigned char *pData = 0;
126 2 : const unsigned char *const pTextOrig = reinterpret_cast<const unsigned char *>(aText);
127 2 : const unsigned char *pText = pTextOrig;
128 :
129 : // reading by small pieces
130 2 : pData = pInput->read(1UL, nReadBytes);
131 2 : CPPUNIT_ASSERT_EQUAL(1UL, nReadBytes);
132 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
133 2 : CPPUNIT_ASSERT(!pInput->isEnd());
134 2 : pText += nReadBytes;
135 :
136 2 : pData = pInput->read(2UL, nReadBytes);
137 2 : CPPUNIT_ASSERT_EQUAL(2UL, nReadBytes);
138 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
139 2 : CPPUNIT_ASSERT(!pInput->isEnd());
140 2 : pText += nReadBytes;
141 :
142 2 : pData = pInput->read(3UL, nReadBytes);
143 2 : CPPUNIT_ASSERT_EQUAL(3UL, nReadBytes);
144 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
145 2 : CPPUNIT_ASSERT(!pInput->isEnd());
146 2 : pText += nReadBytes;
147 :
148 : assert(nLen > 6);
149 2 : pData = pInput->read(nLen - 6, nReadBytes);
150 2 : CPPUNIT_ASSERT_EQUAL(nLen - 6, nReadBytes);
151 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
152 2 : CPPUNIT_ASSERT(pInput->isEnd());
153 :
154 : // reading everything at once
155 2 : pInput->seek(0, RVNG_SEEK_SET);
156 2 : pText = pTextOrig;
157 :
158 2 : pData = pInput->read(nLen, nReadBytes);
159 2 : CPPUNIT_ASSERT_EQUAL(nLen, nReadBytes);
160 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
161 2 : CPPUNIT_ASSERT(pInput->isEnd());
162 :
163 : // trying to read too much
164 2 : pInput->seek(0, RVNG_SEEK_SET);
165 2 : pText = pTextOrig;
166 :
167 2 : pData = pInput->read(nLen + 1, nReadBytes);
168 2 : CPPUNIT_ASSERT_EQUAL(nLen, nReadBytes);
169 2 : CPPUNIT_ASSERT(equal(pText, pText + nReadBytes, pData));
170 2 : CPPUNIT_ASSERT(pInput->isEnd());
171 :
172 : // trying to read nothing
173 2 : pInput->seek(0, RVNG_SEEK_SET);
174 2 : pText = pTextOrig;
175 :
176 2 : pData = pInput->read(0UL, nReadBytes);
177 2 : CPPUNIT_ASSERT_EQUAL(0UL, nReadBytes);
178 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
179 2 : CPPUNIT_ASSERT_EQUAL(pData, static_cast<const unsigned char *>(0));
180 2 : CPPUNIT_ASSERT(!pInput->isEnd());
181 2 : }
182 :
183 2 : void WPXSvStreamTest::testSeekSet()
184 : {
185 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
186 2 : const long nLen = sizeof aText;
187 :
188 : // check initial state
189 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
190 2 : CPPUNIT_ASSERT(!pInput->isEnd());
191 :
192 : // valid seeks
193 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
194 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
195 2 : CPPUNIT_ASSERT(!pInput->isEnd());
196 :
197 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(1, RVNG_SEEK_SET));
198 2 : CPPUNIT_ASSERT_EQUAL(1L, pInput->tell());
199 2 : CPPUNIT_ASSERT(!pInput->isEnd());
200 :
201 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(nLen, RVNG_SEEK_SET));
202 2 : CPPUNIT_ASSERT(nLen == pInput->tell());
203 2 : CPPUNIT_ASSERT(pInput->isEnd());
204 :
205 : // go back to the beginning
206 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
207 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
208 :
209 : // invalid seeks
210 2 : CPPUNIT_ASSERT(0 != pInput->seek(-1, RVNG_SEEK_SET));
211 : // Okay, this is not defined. But it is what the WPXSvInputStream
212 : // does ATM and it is reasonable.
213 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
214 2 : CPPUNIT_ASSERT(!pInput->isEnd());
215 :
216 2 : CPPUNIT_ASSERT(0 != pInput->seek(nLen + 1, RVNG_SEEK_SET));
217 2 : CPPUNIT_ASSERT(nLen == pInput->tell());
218 2 : CPPUNIT_ASSERT(pInput->isEnd());
219 2 : }
220 :
221 2 : void WPXSvStreamTest::testSeekCur()
222 : {
223 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
224 2 : const long nLen = sizeof aText;
225 :
226 : // check initial state
227 2 : CPPUNIT_ASSERT(!pInput->isEnd());
228 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
229 :
230 : // valid seeks
231 :
232 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_CUR));
233 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
234 2 : CPPUNIT_ASSERT(!pInput->isEnd());
235 :
236 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(1, RVNG_SEEK_CUR));
237 2 : CPPUNIT_ASSERT_EQUAL(1L, pInput->tell());
238 2 : CPPUNIT_ASSERT(!pInput->isEnd());
239 :
240 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-1, RVNG_SEEK_CUR));
241 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
242 2 : CPPUNIT_ASSERT(!pInput->isEnd());
243 :
244 : // go back to the beginning
245 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
246 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
247 :
248 : // invalid seeks
249 2 : CPPUNIT_ASSERT(0 != pInput->seek(-1, RVNG_SEEK_CUR));
250 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
251 2 : CPPUNIT_ASSERT(!pInput->isEnd());
252 :
253 2 : CPPUNIT_ASSERT(0 != pInput->seek(nLen + 1, RVNG_SEEK_CUR));
254 2 : CPPUNIT_ASSERT(nLen == pInput->tell());
255 2 : CPPUNIT_ASSERT(pInput->isEnd());
256 2 : }
257 :
258 2 : void WPXSvStreamTest::testSeekEnd()
259 : {
260 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
261 2 : const long nLen = sizeof aText;
262 :
263 : // check initial state
264 2 : CPPUNIT_ASSERT(!pInput->isEnd());
265 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
266 :
267 : // valid seeks
268 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_END));
269 2 : CPPUNIT_ASSERT(nLen == pInput->tell());
270 2 : CPPUNIT_ASSERT(pInput->isEnd());
271 :
272 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-1, RVNG_SEEK_END));
273 2 : CPPUNIT_ASSERT((nLen - 1) == pInput->tell());
274 2 : CPPUNIT_ASSERT(!pInput->isEnd());
275 :
276 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(-nLen, RVNG_SEEK_END));
277 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
278 2 : CPPUNIT_ASSERT(!pInput->isEnd());
279 :
280 : // go back to the beginning
281 2 : CPPUNIT_ASSERT_EQUAL(0, pInput->seek(0, RVNG_SEEK_SET));
282 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
283 :
284 : // invalid seeks
285 2 : CPPUNIT_ASSERT(0 != pInput->seek(1, RVNG_SEEK_END));
286 2 : CPPUNIT_ASSERT(nLen == pInput->tell());
287 2 : CPPUNIT_ASSERT(pInput->isEnd());
288 :
289 2 : CPPUNIT_ASSERT(0 != pInput->seek(-nLen - 1, RVNG_SEEK_END));
290 2 : CPPUNIT_ASSERT_EQUAL(0L, pInput->tell());
291 2 : CPPUNIT_ASSERT(!pInput->isEnd());
292 2 : }
293 :
294 2 : void WPXSvStreamTest::testStructured()
295 : {
296 : // OLE2
297 : {
298 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStreamForURL(getURLFromSrc(aOLEFile)));
299 : assert(bool(pInput));
300 :
301 2 : CPPUNIT_ASSERT(pInput->isStructured());
302 2 : CPPUNIT_ASSERT(2 == pInput->subStreamCount());
303 2 : lcl_testSubStreams(pInput);
304 :
305 : // check for existing substream
306 2 : CPPUNIT_ASSERT(pInput->existsSubStream("WordDocument"));
307 4 : shared_ptr<RVNGInputStream> pSubStream(pInput->getSubStreamByName("WordDocument"));
308 2 : CPPUNIT_ASSERT(bool(pSubStream));
309 2 : CPPUNIT_ASSERT(!pSubStream->isEnd());
310 :
311 : // check for not existing substream
312 2 : CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
313 2 : pSubStream.reset(pInput->getSubStreamByName("foo"));
314 4 : CPPUNIT_ASSERT(!pSubStream);
315 : }
316 :
317 : // Zip
318 : {
319 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStreamForURL(getURLFromSrc(aZipFile)));
320 : assert(bool(pInput));
321 :
322 2 : CPPUNIT_ASSERT(pInput->isStructured());
323 2 : CPPUNIT_ASSERT(9 == pInput->subStreamCount());
324 2 : lcl_testSubStreams(pInput);
325 :
326 : // check for existing substream
327 2 : CPPUNIT_ASSERT(pInput->existsSubStream("content.xml"));
328 4 : shared_ptr<RVNGInputStream> pSubStream(pInput->getSubStreamByName("content.xml"));
329 2 : CPPUNIT_ASSERT(bool(pSubStream));
330 2 : CPPUNIT_ASSERT(!pSubStream->isEnd());
331 :
332 : // check for not existing substream
333 2 : CPPUNIT_ASSERT(pInput->existsSubStream("content.xml"));
334 2 : CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
335 2 : pSubStream.reset(pInput->getSubStreamByName("foo"));
336 4 : CPPUNIT_ASSERT(!pSubStream);
337 : }
338 :
339 : // not structured
340 : {
341 2 : const shared_ptr<RVNGInputStream> pInput(lcl_createStream());
342 :
343 2 : CPPUNIT_ASSERT(!pInput->isStructured());
344 2 : CPPUNIT_ASSERT(0 == pInput->subStreamCount());
345 2 : CPPUNIT_ASSERT(!pInput->existsSubStream("foo"));
346 2 : CPPUNIT_ASSERT(0 == pInput->getSubStreamByName("foo"));
347 2 : CPPUNIT_ASSERT(0 == pInput->getSubStreamById(42));
348 2 : CPPUNIT_ASSERT(0 == pInput->subStreamName(42));
349 : }
350 2 : }
351 :
352 2 : CPPUNIT_TEST_SUITE_REGISTRATION(WPXSvStreamTest);
353 :
354 6 : }
355 :
356 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|