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