1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
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
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.
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.
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,
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.
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.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 /*************************************************************************
59 ************************************************************************/
60 #include "lwpfilter.hxx"
61 #include "lwpresource.hxx"
63 #include "xfilter/xfsaxstream.hxx"
65 #include "lwp9reader.hxx"
66 #include "lwpsvstream.hxx"
68 #include "xfilter/xffontfactory.hxx"
69 #include "xfilter/xfstylemanager.hxx"
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>
81 #include <tools/stream.hxx>
82 #include <sfx2/docfile.hxx>
84 #include <boost/scoped_ptr.hpp>
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 ::com::sun::star::uno::Sequence
;
98 sal_Bool
IsWordproFile( uno::Reference
<XInputStream
>& rInputStream
);
99 sal_Bool
IsWordproFile(OUString file
);
101 LWPFilterReader::LWPFilterReader()
105 LWPFilterReader::~LWPFilterReader()
109 sal_Bool
LWPFilterReader::filter( const Sequence
< PropertyValue
>& aDescriptor
)
110 throw( RuntimeException
)
113 for( sal_Int32 i
= 0; i
< aDescriptor
.getLength(); i
++ )
115 //Note we should attempt to use "InputStream" if it exists first!
116 if ( aDescriptor
[i
].Name
== "URL" )
117 aDescriptor
[i
].Value
>>= sURL
;
120 SvFileStream
inputStream( sURL
, STREAM_READ
);
121 if ( inputStream
.IsEof() || ( inputStream
.GetError() != SVSTREAM_OK
) )
124 return (ReadWordproFile(inputStream
, m_DocumentHandler
) == 0);
127 void LWPFilterReader::cancel() throw (com::sun::star::uno::RuntimeException
)
131 uno::Reference
< XInterface
> LWPFilterImportFilter_CreateInstance(
132 const uno::Reference
< XMultiServiceFactory
>& rSMgr
) throw( Exception
)
134 LWPFilterImportFilter
*p
= new LWPFilterImportFilter( rSMgr
);
136 return uno::Reference
< XInterface
> ( (OWeakObject
* )p
);
139 LWPFilterImportFilter::LWPFilterImportFilter( const uno::Reference
< XMultiServiceFactory
>& xFact
)
143 uno::Reference
< XDocumentHandler
> xDoc( xFact
->createInstance( OUString( STR_WRITER_IMPORTER_NAME
) ), UNO_QUERY
);
145 LWPFilterReader
*p
= new LWPFilterReader
;
146 p
->setDocumentHandler( xDoc
);
148 uno::Reference
< XImporter
> xImporter
= uno::Reference
< XImporter
>( xDoc
, UNO_QUERY
);
149 rImporter
= xImporter
;
150 uno::Reference
< XFilter
> xFilter
= uno::Reference
< XFilter
>( p
);
159 LWPFilterImportFilter::~LWPFilterImportFilter()
163 sal_Bool
LWPFilterImportFilter::filter( const Sequence
< PropertyValue
>& aDescriptor
)
164 throw( RuntimeException
)
166 sal_Bool ret
= rFilter
->filter( aDescriptor
);
171 void LWPFilterImportFilter::cancel() throw (::com::sun::star::uno::RuntimeException
)
176 void LWPFilterImportFilter::setTargetDocument( const uno::Reference
< XComponent
>& xDoc
)
177 throw( IllegalArgumentException
, RuntimeException
)
179 rImporter
->setTargetDocument( xDoc
);
182 OUString
LWPFilterImportFilter::getImplementationName() throw()
184 return OUString( STR_IMPLEMENTATION_NAME
);
187 sal_Bool
LWPFilterImportFilter::supportsService( const OUString
& ServiceName
) throw()
189 Sequence
< OUString
> aSNL
= getSupportedServiceNames();
190 const OUString
*pArray
= aSNL
.getConstArray();
192 for ( sal_Int32 i
= 0; i
< aSNL
.getLength(); i
++ )
194 if ( pArray
[i
] == ServiceName
) return sal_True
;
200 Sequence
< OUString
> LWPFilterImportFilter::getSupportedServiceNames( void ) throw()
202 Sequence
< OUString
> seq(1);
203 seq
.getArray()[0] = OUString( STR_SERVICE_NAME
);
208 OUString SAL_CALL
LWPFilterImportFilter::detect( ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
>& aDescriptor
)
209 throw (::com::sun::star::uno::RuntimeException
)
212 OUString aTypeName
; // a name describing the type (from MediaDescriptor, usually from flat detection)
213 // opening as template is done when a parameter tells to do so and a template filter can be detected
214 // (otherwise no valid filter would be found) or if the detected filter is a template filter and
215 // there is no parameter that forbids to open as template
216 sal_Bool bOpenAsTemplate
= sal_False
;
217 sal_Int32 nPropertyCount
= aDescriptor
.getLength();
218 for( sal_Int32 nProperty
=0; nProperty
<nPropertyCount
; ++nProperty
)
220 if ( aDescriptor
[nProperty
].Name
== "TypeName" )
222 aDescriptor
[nProperty
].Value
>>= aTypeName
;
224 else if ( aDescriptor
[nProperty
].Name
== "AsTemplate" )
226 bOpenAsTemplate
= sal_True
;
230 for( sal_Int32 i
= 0; i
< aDescriptor
.getLength(); i
++ )
233 aDescriptor
[i
].Value
>>= strTemp
;
234 if ( aDescriptor
[i
].Name
== "InputStream" )
236 uno::Reference
< XInputStream
> rInputStream
;
237 aDescriptor
[i
].Value
>>= rInputStream
;
239 // TODO TRANSFORM IMPLEMENTATION HERE!!!!!!
240 // and call m_DocumentHandler's SAX mDochods
242 if( IsWordproFile(rInputStream
) )
244 if ( aTypeName
== "wordpro_template" )
248 aDescriptor
.realloc( nPropertyCount
+ 1 );
249 aDescriptor
[nPropertyCount
].Name
= OUString("AsTemplate");
250 aDescriptor
[nPropertyCount
].Value
<<= sal_True
;
252 return OUString("wordpro_template");
256 return OUString("wordpro");
261 else if ( aDescriptor
[i
].Name
== "URL" )
265 aDescriptor
[i
].Value
>>= sURL
;
267 osl::FileBase::RC rc = osl::FileBase::getSystemPathFromFileURL( sURL, sFileName );
268 if(rc != osl::FileBase::E_None)
271 except.Message = OUString( "GDocting system path from URL failed!");
276 if( IsWordproFile(sURL
) )
278 if ( aTypeName
== "wordpro_template" )
282 aDescriptor
.realloc( nPropertyCount
+ 1 );
283 aDescriptor
[nPropertyCount
].Name
= OUString("AsTemplate");
284 aDescriptor
[nPropertyCount
].Value
<<= sal_True
;
286 return OUString("wordpro_template");
290 return OUString("wordpro");
300 * @descr decompressed small file
301 * @param pCompressed - real file stream
302 * @param pDecompressed - file decompressed, create inside, caller should delete it
303 * @return success - sal_True, fail - sal_False
306 using namespace OpenStormBento
;
307 #include "explode.hxx"
308 sal_Bool
Decompress(SvStream
*pCompressed
, SvStream
* & pOutDecompressed
)
310 pCompressed
->Seek(0);
311 std::auto_ptr
<SvStream
> aDecompressed(new SvMemoryStream(4096, 4096));
312 unsigned char buffer
[512];
313 pCompressed
->Read(buffer
, 16);
314 aDecompressed
->Write(buffer
, 16);
316 boost::scoped_ptr
<LwpSvStream
> aLwpStream(new LwpSvStream(pCompressed
));
317 LtcBenContainer
* pBentoContainer
;
318 sal_uLong ulRet
= BenOpenContainer(aLwpStream
.get(), &pBentoContainer
);
319 if (ulRet
!= BenErr_OK
)
322 boost::scoped_ptr
<LtcUtBenValueStream
> aWordProData((LtcUtBenValueStream
*)pBentoContainer
->FindValueStreamWithPropertyName("WordProData"));
324 if (!aWordProData
.get())
328 Decompression
decompress(aWordProData
.get(), aDecompressed
.get());
329 if (0!= decompress
.explode())
332 sal_uInt32 nPos
= aWordProData
->GetSize();
335 pCompressed
->Seek(nPos
);
336 while (sal_uInt32 iRead
= pCompressed
->Read(buffer
, 512))
337 aDecompressed
->Write(buffer
, iRead
);
339 //transfer ownership of aDecompressed's ptr
340 pOutDecompressed
= aDecompressed
.release();
345 * @descr Get LwpSvStream, if small file, both compressed/decompressed stream
346 * Otherwise, only normal stream
347 * @param pStream - real file stream
348 * @param LwpSvStream * , created inside, deleted outside
349 * @param sal_Bool, sal_True -
351 sal_Bool
GetLwpSvStream(SvStream
*pStream
, LwpSvStream
* & pLwpSvStream
)
353 SvStream
* pDecompressed
= NULL
;
358 if (nTag
!= 0x3750574c) // "LWP7"
360 // small file, needs decompression
361 if (!Decompress(pStream
, pDecompressed
))
367 pDecompressed
->Seek(0);
371 sal_Bool bCompressed
= sal_False
;
374 LwpSvStream
*pOriginalLwpSvStream
= new LwpSvStream(pStream
);
375 pLwpSvStream
= new LwpSvStream(pDecompressed
, pOriginalLwpSvStream
);
376 bCompressed
= sal_True
;
380 pLwpSvStream
= new LwpSvStream(pStream
);
384 int ReadWordproFile(SvStream
&rStream
, uno::Reference
<XDocumentHandler
>& xHandler
)
388 LwpSvStream
*pRawLwpSvStream
= NULL
;
389 boost::scoped_ptr
<LwpSvStream
> aLwpSvStream
;
390 boost::scoped_ptr
<LwpSvStream
> aCompressedLwpSvStream
;
391 boost::scoped_ptr
<SvStream
> aDecompressed
;
392 if (GetLwpSvStream(&rStream
, pRawLwpSvStream
) && pRawLwpSvStream
)
394 SvStream
*pDecompressed
= pRawLwpSvStream
->GetStream();
397 aDecompressed
.reset(pDecompressed
);
398 aCompressedLwpSvStream
.reset(pRawLwpSvStream
->GetCompressedStream());
402 if (!pRawLwpSvStream
)
404 // nothing returned, fail when uncompressing
408 aLwpSvStream
.reset(pRawLwpSvStream
);
410 boost::scoped_ptr
<IXFStream
> pStrm(new XFSaxStream(xHandler
));
411 Lwp9Reader
reader(aLwpSvStream
.get(), pStrm
.get());
412 //Reset all static objects,because this function may be called many times.
424 void ErrorMsg(int /*iErrCode*/)
430 * @descr Compare if pBuf equals with the first 16 bytes
431 * @param pBuf that contains the file data
432 * @return if equals with the Word Pro characteristic strings
434 sal_Bool
IsWordProStr(const sal_Int8
*pBuf
)
436 sal_Bool bRet
= sal_True
;
437 const sal_Int8 pLotusLwp
[] =
439 0x57, 0x6F, 0x72, 0x64,
442 for(size_t i
=0; i
<sizeof(pLotusLwp
); ++i
)
444 if( pBuf
[i
] != pLotusLwp
[i
] )
452 sal_Bool
IsWordproFile(OUString file
)
454 sal_Bool bRet
= sal_False
;
455 SfxMedium
aMedium( file
, STREAM_STD_READ
);
456 SvStream
* pStm
= aMedium
.GetInStream();
463 pStm
->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
464 pStm
->Seek(STREAM_SEEK_TO_BEGIN
);
465 sal_Size nRead
= pStm
->Read(buf
, sizeof(buf
));
466 if( nRead
< sizeof(buf
) )
469 bRet
= IsWordProStr(buf
);
475 sal_Bool
IsWordproFile( uno::Reference
<XInputStream
>& rInputStream
)
477 Sequence
<sal_Int8
> aData
;
478 sal_Bool bRet
= sal_False
;
480 sal_Int32 nRead
= rInputStream
->readBytes(aData
, 16);
487 const sal_Int8
*data
= aData
.getConstArray();
488 bRet
= IsWordProStr(data
);
493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */