Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * The Contents of this file are made available subject to the terms of
5 : : * either of the following licenses
6 : : *
7 : : * - GNU Lesser General Public License Version 2.1
8 : : * - Sun Industry Standards Source License Version 1.1
9 : : *
10 : : * Sun Microsystems Inc., October, 2000
11 : : *
12 : : * GNU Lesser General Public License Version 2.1
13 : : * =============================================
14 : : * Copyright 2000 by Sun Microsystems, Inc.
15 : : * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 : : *
17 : : * This library is free software; you can redistribute it and/or
18 : : * modify it under the terms of the GNU Lesser General Public
19 : : * License version 2.1, as published by the Free Software Foundation.
20 : : *
21 : : * This library is distributed in the hope that it will be useful,
22 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : * Lesser General Public License for more details.
25 : : *
26 : : * You should have received a copy of the GNU Lesser General Public
27 : : * License along with this library; if not, write to the Free Software
28 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 : : * MA 02111-1307 USA
30 : : *
31 : : *
32 : : * Sun Industry Standards Source License Version 1.1
33 : : * =================================================
34 : : * The contents of this file are subject to the Sun Industry Standards
35 : : * Source License Version 1.1 (the "License"); You may not use this file
36 : : * except in compliance with the License. You may obtain a copy of the
37 : : * License at http://www.openoffice.org/license.html.
38 : : *
39 : : * Software provided under this License is provided on an "AS IS" basis,
40 : : * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 : : * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 : : * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 : : * See the License for the specific provisions governing your rights and
44 : : * obligations concerning the Software.
45 : : *
46 : : * The Initial Developer of the Original Code is: IBM Corporation
47 : : *
48 : : * Copyright: 2008 by IBM Corporation
49 : : *
50 : : * All Rights Reserved.
51 : : *
52 : : * Contributor(s): _______________________________________
53 : : *
54 : : *
55 : : ************************************************************************/
56 : : /*************************************************************************
57 : : * @file
58 : : * Circle object.
59 : : ************************************************************************/
60 : : #include "lwpfilter.hxx"
61 : : #include "lwpresource.hxx"
62 : : //for sax stream
63 : : #include "xfilter/xfsaxstream.hxx"
64 : : //for file parser
65 : : #include "lwp9reader.hxx"
66 : : #include "lwpsvstream.hxx"
67 : : //for container reset
68 : : #include "xfilter/xffontfactory.hxx"
69 : : #include "xfilter/xfstylemanager.hxx"
70 : :
71 : : #include <osl/file.h>
72 : : #include <osl/file.hxx>
73 : : #include <vcl/svapp.hxx>
74 : : #include <xmloff/attrlist.hxx>
75 : : #include <com/sun/star/io/IOException.hpp>
76 : : #include <com/sun/star/frame/XDesktop.hpp>
77 : : #include <com/sun/star/frame/XController.hpp>
78 : : #include <com/sun/star/text/XTextDocument.hpp>
79 : : #include <com/sun/star/text/XText.hpp>
80 : :
81 : : #include <tools/stream.hxx>
82 : : #include <sfx2/docfile.hxx>
83 : :
84 : : #include <boost/scoped_ptr.hpp>
85 : :
86 : : using namespace ::cppu;
87 : : using namespace ::com::sun::star::lang;
88 : : using namespace ::com::sun::star::frame;
89 : : using namespace ::com::sun::star::text;
90 : : using namespace ::com::sun::star::io;
91 : : using namespace ::com::sun::star::registry;
92 : : using namespace ::com::sun::star::document;
93 : : using namespace ::com::sun::star::beans;
94 : : using namespace ::com::sun::star::xml::sax;
95 : : using namespace ::com::sun::star;
96 : : using ::rtl::OUString;
97 : : using ::com::sun::star::uno::Sequence;
98 : :
99 : : sal_Bool IsWordproFile( uno::Reference<XInputStream>& rInputStream);
100 : : sal_Bool IsWordproFile(rtl::OUString file);
101 : :
102 : 0 : LWPFilterReader::LWPFilterReader()
103 : : {
104 : 0 : }
105 : :
106 : 0 : LWPFilterReader::~LWPFilterReader()
107 : : {
108 [ # # ]: 0 : }
109 : :
110 : 0 : sal_Bool LWPFilterReader::filter( const Sequence< PropertyValue >& aDescriptor )
111 : : throw( RuntimeException )
112 : : {
113 : 0 : ::rtl::OUString sURL;
114 [ # # ]: 0 : for( sal_Int32 i = 0; i < aDescriptor.getLength(); i++ )
115 : : {
116 : : //Note we should attempt to use "InputStream" if it exists first!
117 [ # # ]: 0 : if ( aDescriptor[i].Name == "URL" )
118 : 0 : aDescriptor[i].Value >>= sURL;
119 : : }
120 : :
121 [ # # ][ # # ]: 0 : SvFileStream inputStream( sURL, STREAM_READ );
[ # # ]
122 [ # # ][ # # ]: 0 : if ( inputStream.IsEof() || ( inputStream.GetError() != SVSTREAM_OK ) )
[ # # ]
123 : 0 : return sal_False;
124 : :
125 [ # # ][ # # ]: 0 : return (ReadWordproFile(inputStream, m_DocumentHandler) == 0);
126 : : }
127 : :
128 : 0 : void LWPFilterReader::cancel() throw (com::sun::star::uno::RuntimeException)
129 : : {
130 : 0 : }
131 : :
132 : 0 : uno::Reference< XInterface > LWPFilterImportFilter_CreateInstance(
133 : : const uno::Reference< XMultiServiceFactory >& rSMgr ) throw( Exception )
134 : : {
135 [ # # ]: 0 : LWPFilterImportFilter *p = new LWPFilterImportFilter( rSMgr );
136 : :
137 : 0 : return uno::Reference< XInterface > ( (OWeakObject* )p );
138 : : }
139 : :
140 : 0 : LWPFilterImportFilter::LWPFilterImportFilter( const uno::Reference< XMultiServiceFactory >& xFact )
141 : : {
142 : : try
143 : : {
144 [ # # ][ # # ]: 0 : uno::Reference< XDocumentHandler > xDoc( xFact->createInstance( OUString( STR_WRITER_IMPORTER_NAME ) ), UNO_QUERY );
[ # # ]
145 : :
146 [ # # ]: 0 : LWPFilterReader *p = new LWPFilterReader;
147 [ # # ]: 0 : p->setDocumentHandler( xDoc );
148 : :
149 [ # # ]: 0 : uno::Reference< XImporter > xImporter = uno::Reference< XImporter >( xDoc, UNO_QUERY );
150 [ # # ]: 0 : rImporter = xImporter;
151 [ # # ][ # # ]: 0 : uno::Reference< XFilter > xFilter = uno::Reference< XFilter >( p );
152 [ # # ][ # # ]: 0 : rFilter = xFilter;
153 : : }
154 : 0 : catch( Exception & )
155 : : {
156 : 0 : exit( 1 );
157 : : }
158 : 0 : }
159 : :
160 : 0 : LWPFilterImportFilter::~LWPFilterImportFilter()
161 : : {
162 [ # # ]: 0 : }
163 : :
164 : 0 : sal_Bool LWPFilterImportFilter::filter( const Sequence< PropertyValue >& aDescriptor )
165 : : throw( RuntimeException )
166 : : {
167 : 0 : sal_Bool ret = rFilter->filter( aDescriptor );
168 : :
169 : 0 : return ret;
170 : : }
171 : :
172 : 0 : void LWPFilterImportFilter::cancel() throw (::com::sun::star::uno::RuntimeException)
173 : : {
174 : 0 : rFilter->cancel();
175 : 0 : }
176 : :
177 : 0 : void LWPFilterImportFilter::setTargetDocument( const uno::Reference< XComponent >& xDoc )
178 : : throw( IllegalArgumentException, RuntimeException )
179 : : {
180 : 0 : rImporter->setTargetDocument( xDoc );
181 : 0 : }
182 : :
183 : 0 : OUString LWPFilterImportFilter::getImplementationName() throw()
184 : : {
185 : 0 : return OUString( STR_IMPLEMENTATION_NAME );
186 : : }
187 : :
188 : 0 : sal_Bool LWPFilterImportFilter::supportsService( const OUString& ServiceName ) throw()
189 : : {
190 : 0 : Sequence< OUString > aSNL = getSupportedServiceNames();
191 : 0 : const OUString *pArray = aSNL.getConstArray();
192 : :
193 [ # # ]: 0 : for ( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
194 : : {
195 [ # # ]: 0 : if ( pArray[i] == ServiceName ) return sal_True;
196 : : }
197 : :
198 [ # # ]: 0 : return sal_False;
199 : : }
200 : :
201 : 0 : Sequence< OUString> LWPFilterImportFilter::getSupportedServiceNames( void ) throw()
202 : : {
203 : 0 : Sequence< OUString > seq(1);
204 [ # # ]: 0 : seq.getArray()[0] = OUString( STR_SERVICE_NAME );
205 : 0 : return seq;
206 : : }
207 : :
208 : :
209 : 0 : ::rtl::OUString SAL_CALL LWPFilterImportFilter::detect( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
210 : : throw (::com::sun::star::uno::RuntimeException)
211 : : {
212 : 0 : rtl::OUString ret;
213 : 0 : rtl::OUString aTypeName; // a name describing the type (from MediaDescriptor, usually from flat detection)
214 : : // opening as template is done when a parameter tells to do so and a template filter can be detected
215 : : // (otherwise no valid filter would be found) or if the detected filter is a template filter and
216 : : // there is no parameter that forbids to open as template
217 : 0 : sal_Bool bOpenAsTemplate = sal_False;
218 : 0 : sal_Int32 nPropertyCount = aDescriptor.getLength();
219 [ # # ]: 0 : for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
220 : : {
221 [ # # ][ # # ]: 0 : if ( aDescriptor[nProperty].Name == "TypeName" )
222 : : {
223 [ # # ]: 0 : aDescriptor[nProperty].Value >>= aTypeName;
224 : : }
225 [ # # ][ # # ]: 0 : else if ( aDescriptor[nProperty].Name == "AsTemplate" )
226 : : {
227 : 0 : bOpenAsTemplate = sal_True;
228 : : }
229 : : }
230 : :
231 [ # # ]: 0 : for( sal_Int32 i = 0; i < aDescriptor.getLength(); i++ )
232 : : {
233 : 0 : OUString strTemp;
234 [ # # ]: 0 : aDescriptor[i].Value >>= strTemp;
235 [ # # ][ # # ]: 0 : if ( aDescriptor[i].Name == "InputStream" )
236 : : {
237 : 0 : uno::Reference< XInputStream> rInputStream;
238 [ # # ][ # # ]: 0 : aDescriptor[i].Value >>= rInputStream;
239 : : //
240 : : // TODO TRANSFORM IMPLEMENTATION HERE!!!!!!
241 : : // and call m_DocumentHandler's SAX mDochods
242 : : //
243 [ # # ][ # # ]: 0 : if( IsWordproFile(rInputStream) )
244 : : {
245 [ # # ]: 0 : if ( aTypeName == "wordpro_template" )
246 : : {
247 [ # # ]: 0 : if(!bOpenAsTemplate)
248 : : {
249 [ # # ]: 0 : aDescriptor.realloc( nPropertyCount + 1 );
250 [ # # ]: 0 : aDescriptor[nPropertyCount].Name = ::rtl::OUString("AsTemplate");
251 [ # # ][ # # ]: 0 : aDescriptor[nPropertyCount].Value <<= sal_True;
252 : : }
253 : 0 : return OUString("wordpro_template");
254 : : }
255 : : else
256 : : {
257 : 0 : return OUString("wordpro");
258 : : }
259 : : }
260 : 0 : return ret;
261 : : }
262 [ # # ][ # # ]: 0 : else if ( aDescriptor[i].Name == "URL" )
263 : : {
264 : 0 : OUString sURL;
265 : 0 : OUString sFileName;
266 : :
267 [ # # ]: 0 : aDescriptor[i].Value >>= sURL;
268 : : /*
269 : : osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL( sURL, sFileName );
270 : : if(rc != osl::FileBase::E_None)
271 : : {
272 : : SAXException except;
273 : : except.Message = OUString( "GDocting system path from URL failed!");
274 : : throw except;
275 : : }
276 : : */
277 : : //end with .lwp:
278 [ # # ][ # # ]: 0 : if( IsWordproFile(sURL) )
279 : : {
280 [ # # ]: 0 : if ( aTypeName == "wordpro_template" )
281 : : {
282 [ # # ]: 0 : if(!bOpenAsTemplate)
283 : : {
284 [ # # ]: 0 : aDescriptor.realloc( nPropertyCount + 1 );
285 [ # # ]: 0 : aDescriptor[nPropertyCount].Name = ::rtl::OUString("AsTemplate");
286 [ # # ][ # # ]: 0 : aDescriptor[nPropertyCount].Value <<= sal_True;
287 : : }
288 : 0 : return OUString("wordpro_template");
289 : : }
290 : : else
291 : : {
292 : 0 : return OUString("wordpro");
293 : : }
294 : : }
295 : 0 : return ret;
296 : : }
297 [ # # ]: 0 : }
298 : 0 : return ret;
299 : : }
300 : :
301 : : /**
302 : : * @descr decompressed small file
303 : : * @param pCompressed - real file stream
304 : : * @param pDecompressed - file decompressed, create inside, caller should delete it
305 : : * @return success - sal_True, fail - sal_False
306 : : */
307 : : #include "bento.hxx"
308 : : using namespace OpenStormBento;
309 : : #include "explode.hxx"
310 : 0 : sal_Bool Decompress(SvStream *pCompressed, SvStream * & pOutDecompressed)
311 : : {
312 [ # # ]: 0 : pCompressed->Seek(0);
313 [ # # ][ # # ]: 0 : std::auto_ptr<SvStream> aDecompressed(new SvMemoryStream(4096, 4096));
314 : : unsigned char buffer[512];
315 [ # # ]: 0 : pCompressed->Read(buffer, 16);
316 [ # # ]: 0 : aDecompressed->Write(buffer, 16);
317 : :
318 [ # # ][ # # ]: 0 : boost::scoped_ptr<LwpSvStream> aLwpStream(new LwpSvStream(pCompressed));
319 : : LtcBenContainer* pBentoContainer;
320 [ # # ]: 0 : sal_uLong ulRet = BenOpenContainer(aLwpStream.get(), &pBentoContainer);
321 [ # # ]: 0 : if (ulRet != BenErr_OK)
322 : 0 : return sal_False;
323 : :
324 [ # # ]: 0 : boost::scoped_ptr<LtcUtBenValueStream> aWordProData((LtcUtBenValueStream *)pBentoContainer->FindValueStreamWithPropertyName("WordProData"));
325 : :
326 [ # # ]: 0 : if (!aWordProData.get())
327 : 0 : return sal_False;
328 : :
329 : : // decompressing
330 [ # # ]: 0 : Decompression decompress(aWordProData.get(), aDecompressed.get());
331 [ # # ][ # # ]: 0 : if (0!= decompress.explode())
332 : 0 : return sal_False;
333 : :
334 : 0 : sal_uInt32 nPos = aWordProData->GetSize();
335 : 0 : nPos += 0x10;
336 : :
337 [ # # ]: 0 : pCompressed->Seek(nPos);
338 [ # # ][ # # ]: 0 : while (sal_uInt32 iRead = pCompressed->Read(buffer, 512))
339 [ # # ]: 0 : aDecompressed->Write(buffer, iRead);
340 : :
341 : : //transfer ownership of aDecompressed's ptr
342 : 0 : pOutDecompressed = aDecompressed.release();
343 [ # # ][ # # ]: 0 : return sal_True;
[ # # ][ # # ]
344 : : }
345 : :
346 : : /**
347 : : * @descr Get LwpSvStream, if small file, both compressed/decompressed stream
348 : : * Otherwise, only normal stream
349 : : * @param pStream - real file stream
350 : : * @param LwpSvStream * , created inside, deleted outside
351 : : * @param sal_Bool, sal_True -
352 : : */
353 : 18 : sal_Bool GetLwpSvStream(SvStream *pStream, LwpSvStream * & pLwpSvStream)
354 : : {
355 : 18 : SvStream * pDecompressed = NULL;
356 : :
357 : : sal_uInt32 nTag;
358 [ + - ]: 18 : pStream->Seek(0x10);
359 [ + - ]: 18 : *pStream >> nTag;
360 [ - + ]: 18 : if (nTag != 0x3750574c) // "LWP7"
361 : : {
362 : : // small file, needs decompression
363 [ # # ][ # # ]: 0 : if (!Decompress(pStream, pDecompressed))
364 : : {
365 : 0 : pLwpSvStream = NULL;
366 : 0 : return sal_True;
367 : : }
368 [ # # ]: 0 : pStream->Seek(0);
369 [ # # ]: 0 : pDecompressed->Seek(0);
370 : : }
371 : :
372 : 18 : pLwpSvStream = NULL;
373 : 18 : sal_Bool bCompressed = sal_False;
374 [ - + ]: 18 : if (pDecompressed)
375 : : {
376 [ # # ][ # # ]: 0 : LwpSvStream *pOriginalLwpSvStream = new LwpSvStream(pStream);
377 [ # # ][ # # ]: 0 : pLwpSvStream = new LwpSvStream(pDecompressed, pOriginalLwpSvStream);
378 : 0 : bCompressed = sal_True;
379 : : }
380 : : else
381 : : {
382 [ + - ][ + - ]: 18 : pLwpSvStream = new LwpSvStream(pStream);
383 : : }
384 : 18 : return bCompressed;
385 : : }
386 : 18 : int ReadWordproFile(SvStream &rStream, uno::Reference<XDocumentHandler>& xHandler)
387 : : {
388 : : try
389 : : {
390 : 18 : LwpSvStream *pRawLwpSvStream = NULL;
391 : 18 : boost::scoped_ptr<LwpSvStream> aLwpSvStream;
392 : 18 : boost::scoped_ptr<LwpSvStream> aCompressedLwpSvStream;
393 : 18 : boost::scoped_ptr<SvStream> aDecompressed;
394 [ - + ][ # # ]: 18 : if (GetLwpSvStream(&rStream, pRawLwpSvStream) && pRawLwpSvStream)
[ - + ][ + - ]
395 : : {
396 : 0 : SvStream *pDecompressed = pRawLwpSvStream->GetStream();
397 [ # # ]: 0 : if (pDecompressed)
398 : : {
399 [ # # ]: 0 : aDecompressed.reset(pDecompressed);
400 [ # # ]: 0 : aCompressedLwpSvStream.reset(pRawLwpSvStream->GetCompressedStream());
401 : : }
402 : : }
403 : :
404 [ - + ]: 18 : if (!pRawLwpSvStream)
405 : : {
406 : : // nothing returned, fail when uncompressing
407 : 0 : return 1;
408 : : }
409 : :
410 [ + - ]: 18 : aLwpSvStream.reset(pRawLwpSvStream);
411 : :
412 [ + - ][ + - ]: 18 : boost::scoped_ptr<IXFStream> pStrm(new XFSaxStream(xHandler));
413 [ + - ]: 18 : Lwp9Reader reader(aLwpSvStream.get(), pStrm.get());
414 : : //Reset all static objects,because this function may be called many times.
415 [ + - ]: 18 : XFGlobalReset();
416 [ + + ]: 18 : reader.Read();
417 : :
418 [ + - ][ + - ]: 27 : return 0;
[ + - ][ + - ]
419 : : }
420 : 9 : catch (...)
421 : : {
422 : 9 : return 1;
423 : : }
424 : : }
425 : :
426 : 0 : void ErrorMsg(int /*iErrCode*/)
427 : : {
428 : :
429 : 0 : }
430 : :
431 : : /**
432 : : * @descr Compare if pBuf equals with the first 16 bytes
433 : : * @param pBuf that contains the file data
434 : : * @return if equals with the Word Pro characteristic strings
435 : : */
436 : 0 : sal_Bool IsWordProStr(const sal_Int8 *pBuf)
437 : : {
438 : 0 : sal_Bool bRet = sal_True;
439 : : const sal_Int8 pLotusLwp[] =
440 : : {
441 : : 0x57, 0x6F, 0x72, 0x64,
442 : : 0x50, 0x72, 0x6F
443 : 0 : };
444 [ # # ]: 0 : for(size_t i=0; i<sizeof(pLotusLwp); ++i)
445 : : {
446 [ # # ]: 0 : if( pBuf[i] != pLotusLwp[i] )
447 : : {
448 : 0 : bRet = sal_False;
449 : : }
450 : : }
451 : 0 : return bRet;
452 : : }
453 : :
454 : 0 : sal_Bool IsWordproFile(rtl::OUString file)
455 : : {
456 : 0 : sal_Bool bRet = sal_False;
457 [ # # ][ # # ]: 0 : SfxMedium aMedium( file, STREAM_STD_READ);
[ # # ]
458 [ # # ]: 0 : SvStream* pStm = aMedium.GetInStream();
459 : :
460 [ # # ]: 0 : if(pStm)
461 : : {
462 : : sal_Int8 buf[16];
463 : 0 : bRet = sal_True;
464 : :
465 [ # # ]: 0 : pStm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
466 [ # # ]: 0 : pStm->Seek(STREAM_SEEK_TO_BEGIN);
467 [ # # ]: 0 : sal_Size nRead = pStm->Read(buf, sizeof(buf));
468 [ # # ]: 0 : if( nRead< sizeof(buf) )
469 : 0 : bRet = sal_False;
470 : : else
471 : 0 : bRet = IsWordProStr(buf);
472 : : }
473 [ # # ]: 0 : return bRet;
474 : : }
475 : :
476 : :
477 : 0 : sal_Bool IsWordproFile( uno::Reference<XInputStream>& rInputStream)
478 : : {
479 [ # # ]: 0 : Sequence<sal_Int8> aData;
480 : 0 : sal_Bool bRet = sal_False;
481 : :
482 [ # # ][ # # ]: 0 : sal_Int32 nRead = rInputStream->readBytes(aData, 16);
483 [ # # ]: 0 : if( nRead != 16 )
484 : : {
485 : 0 : bRet = sal_False;
486 : : }
487 : : else
488 : : {
489 : 0 : const sal_Int8 *data = aData.getConstArray();
490 : 0 : bRet = IsWordProStr(data);
491 : : }
492 [ # # ]: 0 : return bRet;
493 : : }
494 : :
495 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|