1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "filterdet.hxx"
22 #include "inc/pdfparse.hxx"
24 #include <osl/diagnose.h>
26 #include <osl/thread.h>
27 #include <rtl/digest.h>
28 #include <rtl/ref.hxx>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/beans/XPropertySet.hpp>
31 #include <com/sun/star/awt/XWindow.hpp>
32 #include <com/sun/star/awt/XListBox.hpp>
33 #include <com/sun/star/awt/XDialogEventHandler.hpp>
34 #include <com/sun/star/awt/XDialogProvider2.hpp>
35 #include <com/sun/star/awt/XControlContainer.hpp>
36 #include <com/sun/star/uno/RuntimeException.hpp>
37 #include <com/sun/star/io/XInputStream.hpp>
38 #include <com/sun/star/io/XStream.hpp>
39 #include <com/sun/star/io/XSeekable.hpp>
40 #include <com/sun/star/io/TempFile.hpp>
42 #include <boost/scoped_ptr.hpp>
45 using namespace com::sun::star
;
50 // TODO(T3): locking/thread safety
53 typedef ::cppu::WeakComponentImplHelper1
<
54 com::sun::star::awt::XDialogEventHandler
> ChooserDialogHandlerBase
;
55 class ChooserDialogHandler
: private cppu::BaseMutex
,
56 public ChooserDialogHandlerBase
58 uno::Reference
<awt::XListBox
> m_xListbox
;
59 uno::Reference
<awt::XWindow
> m_xWriterText
;
60 uno::Reference
<awt::XWindow
> m_xDrawText
;
61 uno::Reference
<awt::XWindow
> m_xImpressText
;
63 enum{ DRAW_INDEX
=0, IMPRESS_INDEX
=1, WRITER_INDEX
=2 };
64 void selectionChanged( sal_Int32 nIndex
) const
66 sal_Bool
bWriterState(sal_False
);
67 sal_Bool
bDrawState(sal_False
);
68 sal_Bool
bImpressState(sal_False
);
72 OSL_FAIL("Unexpected case!");
78 bImpressState
=sal_True
;
81 bWriterState
=sal_True
;
84 m_xWriterText
->setVisible(bWriterState
);
85 m_xDrawText
->setVisible(bDrawState
);
86 m_xImpressText
->setVisible(bImpressState
);
89 ChooserDialogHandler() :
90 ChooserDialogHandlerBase(m_aMutex
),
97 void initControls( const uno::Reference
<awt::XControlContainer
>& xControls
,
98 const OUString
& rFilename
)
100 m_xListbox
.set(xControls
->getControl(
101 OUString( "ListBox" )),
102 uno::UNO_QUERY_THROW
);
103 m_xWriterText
.set(xControls
->getControl(
104 OUString( "InfoWriter" )),
105 uno::UNO_QUERY_THROW
);
106 m_xImpressText
.set(xControls
->getControl(
107 OUString( "InfoImpress" )),
108 uno::UNO_QUERY_THROW
);
109 m_xDrawText
.set(xControls
->getControl(
110 OUString( "InfoDraw" )),
111 uno::UNO_QUERY_THROW
);
113 uno::Reference
<awt::XWindow
> xControl
;
114 xControl
.set(xControls
->getControl(
115 OUString( "ListBoxWriter" )),
116 uno::UNO_QUERY_THROW
);
117 xControl
->setVisible(sal_False
);
118 xControl
.set(xControls
->getControl(
119 OUString( "ListBoxImpress" )),
120 uno::UNO_QUERY_THROW
);
121 xControl
->setVisible(sal_False
);
122 xControl
.set(xControls
->getControl(
123 OUString( "ListBoxDraw" )),
124 uno::UNO_QUERY_THROW
);
125 xControl
->setVisible(sal_False
);
126 uno::Reference
<beans::XPropertySet
> xPropSet(
127 xControls
->getControl(
128 OUString( "ComboLabel" ))->getModel(),
129 uno::UNO_QUERY_THROW
);
130 OUString
aFilename( rFilename
.copy(rFilename
.lastIndexOf('/')+1) );
132 xPropSet
->getPropertyValue(OUString( "Label" )) >>= aLabel
;
133 const char pFileName
[] = "%FILENAME";
134 aLabel
= aLabel
.replaceAt(
135 aLabel
.indexOfAsciiL(pFileName
,SAL_N_ELEMENTS(pFileName
)-1),
136 SAL_N_ELEMENTS(pFileName
)-1,
138 xPropSet
->setPropertyValue(OUString( "Label" ),
139 uno::makeAny(aLabel
));
141 uno::Sequence
<OUString
> aListboxItems(3);
142 aListboxItems
[DRAW_INDEX
] = OUString( "Drawing" );
143 aListboxItems
[IMPRESS_INDEX
] = OUString( "Presentation" );
144 aListboxItems
[WRITER_INDEX
] = OUString( "Text Document" );
146 m_xListbox
->addItems(aListboxItems
,0);
147 m_xListbox
->selectItemPos(0,sal_True
);
151 sal_Int32
getSelectedItem() const
153 return m_xListbox
->getSelectedItemPos();
156 virtual ::sal_Bool SAL_CALL
callHandlerMethod( const uno::Reference
< awt::XDialog
>& /*xDialog*/,
157 const uno::Any
& /*EventObject*/,
158 const OUString
& MethodName
) throw (lang::WrappedTargetException
, uno::RuntimeException
)
161 OSL_ENSURE( MethodName
.compareToAscii("SelectionChanged") == 0,
162 "Invalid event name" );
163 selectionChanged(getSelectedItem());
167 virtual uno::Sequence
< OUString
> SAL_CALL
getSupportedMethodNames( ) throw (uno::RuntimeException
)
169 uno::Sequence
< OUString
> aMethods(1);
170 aMethods
[0] = OUString( "SelectionChanged" );
176 class FileEmitContext
: public pdfparse::EmitContext
179 oslFileHandle m_aReadHandle
;
180 unsigned int m_nReadLen
;
181 uno::Reference
< io::XStream
> m_xContextStream
;
182 uno::Reference
< io::XSeekable
> m_xSeek
;
183 uno::Reference
< io::XOutputStream
> m_xOut
;
186 FileEmitContext( const OUString
& rOrigFile
,
187 const uno::Reference
< uno::XComponentContext
>& xContext
,
188 const pdfparse::PDFContainer
* pTop
);
189 virtual ~FileEmitContext();
191 virtual bool write( const void* pBuf
, unsigned int nLen
);
192 virtual unsigned int getCurPos();
193 virtual bool copyOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
);
194 virtual unsigned int readOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
, void* pBuf
);
196 const uno::Reference
< io::XStream
>& getContextStream() const { return m_xContextStream
; }
199 FileEmitContext::FileEmitContext( const OUString
& rOrigFile
,
200 const uno::Reference
< uno::XComponentContext
>& xContext
,
201 const pdfparse::PDFContainer
* pTop
) :
202 pdfparse::EmitContext( pTop
),
209 m_xContextStream
= uno::Reference
< io::XStream
>(
210 io::TempFile::create(xContext
), uno::UNO_QUERY_THROW
);
211 m_xOut
= m_xContextStream
->getOutputStream();
212 m_xSeek
= uno::Reference
<io::XSeekable
>(m_xOut
, uno::UNO_QUERY_THROW
);
214 oslFileError aErr
= osl_File_E_None
;
215 if( (aErr
=osl_openFile( rOrigFile
.pData
,
217 osl_File_OpenFlag_Read
)) == osl_File_E_None
)
219 if( (aErr
=osl_setFilePos( m_aReadHandle
,
221 0 )) == osl_File_E_None
)
223 sal_uInt64 nFileSize
= 0;
224 if( (aErr
=osl_getFilePos( m_aReadHandle
,
225 &nFileSize
)) == osl_File_E_None
)
227 m_nReadLen
= static_cast<unsigned int>(nFileSize
);
230 if( aErr
!= osl_File_E_None
)
232 osl_closeFile( m_aReadHandle
);
233 m_aReadHandle
= NULL
;
239 FileEmitContext::~FileEmitContext()
242 osl_closeFile( m_aReadHandle
);
245 bool FileEmitContext::write( const void* pBuf
, unsigned int nLen
)
250 uno::Sequence
< sal_Int8
> aSeq( nLen
);
251 memcpy( aSeq
.getArray(), pBuf
, nLen
);
252 m_xOut
->writeBytes( aSeq
);
256 unsigned int FileEmitContext::getCurPos()
258 unsigned int nPos
= 0;
261 nPos
= static_cast<unsigned int>( m_xSeek
->getPosition() );
266 bool FileEmitContext::copyOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
)
268 if( nOrigOffset
+ nLen
> m_nReadLen
)
271 if( osl_setFilePos( m_aReadHandle
, osl_Pos_Absolut
, nOrigOffset
) != osl_File_E_None
)
274 uno::Sequence
< sal_Int8
> aSeq( nLen
);
276 sal_uInt64 nBytesRead
= 0;
277 if( osl_readFile( m_aReadHandle
,
280 &nBytesRead
) != osl_File_E_None
281 || nBytesRead
!= static_cast<sal_uInt64
>(nLen
) )
286 m_xOut
->writeBytes( aSeq
);
290 unsigned int FileEmitContext::readOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
, void* pBuf
)
292 if( nOrigOffset
+ nLen
> m_nReadLen
)
295 if( osl_setFilePos( m_aReadHandle
,
297 nOrigOffset
) != osl_File_E_None
)
302 sal_uInt64 nBytesRead
= 0;
303 if( osl_readFile( m_aReadHandle
,
306 &nBytesRead
) != osl_File_E_None
)
310 return static_cast<unsigned int>(nBytesRead
);
314 ////////////////////////////////////////////////////////////////////////////////
317 PDFDetector::PDFDetector( const uno::Reference
< uno::XComponentContext
>& xContext
) :
318 PDFDetectorBase( m_aMutex
),
319 m_xContext( xContext
)
322 // XExtendedFilterDetection
323 OUString SAL_CALL
PDFDetector::detect( uno::Sequence
< beans::PropertyValue
>& rFilterData
) throw( uno::RuntimeException
)
325 osl::MutexGuard
const guard( m_aMutex
);
326 bool bSuccess
= false;
328 // get the InputStream carrying the PDF content
329 uno::Reference
< io::XInputStream
> xInput
;
330 uno::Reference
< io::XStream
> xEmbedStream
;
331 OUString aOutFilterName
, aOutTypeName
;
334 const beans::PropertyValue
* pAttribs
= rFilterData
.getConstArray();
335 sal_Int32 nAttribs
= rFilterData
.getLength();
336 sal_Int32 nFilterNamePos
= -1;
337 sal_Int32 nPwdPos
= -1;
338 for( sal_Int32 i
= 0; i
< nAttribs
; i
++ )
340 #if OSL_DEBUG_LEVEL > 1
341 OUString
aVal( "<no string>" );
342 pAttribs
[i
].Value
>>= aVal
;
343 OSL_TRACE( "doDetection: Attrib: %s = %s\n",
344 OUStringToOString( pAttribs
[i
].Name
, RTL_TEXTENCODING_UTF8
).getStr(),
345 OUStringToOString( aVal
, RTL_TEXTENCODING_UTF8
).getStr() );
347 if ( pAttribs
[i
].Name
== "InputStream" )
348 pAttribs
[i
].Value
>>= xInput
;
349 else if ( pAttribs
[i
].Name
== "URL" )
350 pAttribs
[i
].Value
>>= aURL
;
351 else if ( pAttribs
[i
].Name
== "FilterName" )
353 else if ( pAttribs
[i
].Name
== "Password" )
356 pAttribs
[i
].Value
>>= aPwd
;
361 uno::Reference
< io::XSeekable
> xSeek( xInput
, uno::UNO_QUERY
);
364 // read the first 1024 byte (see PDF reference implementation note 12)
365 const sal_Int32 nHeaderSize
= 1024;
366 uno::Sequence
< sal_Int8
> aBuf( nHeaderSize
);
367 sal_uInt64 nBytes
= 0;
368 nBytes
= xInput
->readBytes( aBuf
, nHeaderSize
);
371 const sal_Int8
* pBytes
= aBuf
.getConstArray();
372 for( unsigned int i
= 0; i
< nBytes
-5; i
++ )
374 if( pBytes
[i
] == '%' &&
375 pBytes
[i
+1] == 'P' &&
376 pBytes
[i
+2] == 'D' &&
377 pBytes
[i
+3] == 'F' &&
386 // check for hybrid PDF
387 oslFileHandle aFile
= NULL
;
389 ( aURL
.isEmpty() || !aURL
.startsWith( "file:" ) )
392 sal_uInt64 nWritten
= 0;
393 if( osl_createTempFile( NULL
, &aFile
, &aURL
.pData
) != osl_File_E_None
)
399 #if OSL_DEBUG_LEVEL > 1
400 OSL_TRACE( "created temp file %s\n",
401 OUStringToOString( aURL
, RTL_TEXTENCODING_UTF8
).getStr() );
403 osl_writeFile( aFile
, aBuf
.getConstArray(), nBytes
, &nWritten
);
405 OSL_ENSURE( nWritten
== nBytes
, "writing of header bytes failed" );
407 if( nWritten
== nBytes
)
409 const sal_uInt32 nBufSize
= 4096;
410 aBuf
= uno::Sequence
<sal_Int8
>(nBufSize
);
414 nBytes
= xInput
->readBytes( aBuf
, nBufSize
);
417 osl_writeFile( aFile
, aBuf
.getConstArray(), nBytes
, &nWritten
);
418 if( nWritten
!= nBytes
)
424 } while( nBytes
== nBufSize
);
427 osl_closeFile( aFile
);
429 OUString aEmbedMimetype
;
430 xEmbedStream
= getAdditionalStream( aURL
, aEmbedMimetype
, aPwd
, m_xContext
, rFilterData
, false );
432 osl_removeFile( aURL
.pData
);
433 if( !aEmbedMimetype
.isEmpty() )
435 if( aEmbedMimetype
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.text" ) )
436 || aEmbedMimetype
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.text-master" ) ) )
437 aOutFilterName
= OUString( "writer_pdf_addstream_import" );
438 else if ( aEmbedMimetype
== "application/vnd.oasis.opendocument.presentation" )
439 aOutFilterName
= OUString( "impress_pdf_addstream_import" );
440 else if( aEmbedMimetype
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.graphics" ) )
441 || aEmbedMimetype
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.drawing" ) ) )
442 aOutFilterName
= OUString( "draw_pdf_addstream_import" );
443 else if ( aEmbedMimetype
== "application/vnd.oasis.opendocument.spreadsheet" )
444 aOutFilterName
= OUString( "calc_pdf_addstream_import" );
450 if( !aOutFilterName
.isEmpty() )
452 if( nFilterNamePos
== -1 )
454 nFilterNamePos
= nAttribs
;
455 rFilterData
.realloc( ++nAttribs
);
456 rFilterData
[ nFilterNamePos
].Name
=
457 OUString( "FilterName" );
459 aOutTypeName
= OUString("pdf_Portable_Document_Format");
461 OSL_TRACE( "setting filter name %s, input stream %s\n",
462 OUStringToOString( aOutFilterName
, RTL_TEXTENCODING_UTF8
).getStr(),
463 xEmbedStream
.is() ? "present" : "not present" );
465 rFilterData
[nFilterNamePos
].Value
<<= aOutFilterName
;
466 if( xEmbedStream
.is() )
468 rFilterData
.realloc( ++nAttribs
);
469 rFilterData
[nAttribs
-1].Name
= OUString( "EmbeddedSubstream" );
470 rFilterData
[nAttribs
-1].Value
<<= xEmbedStream
;
472 if( !aPwd
.isEmpty() )
477 rFilterData
.realloc( ++nAttribs
);
478 rFilterData
[ nPwdPos
].Name
= OUString( "Password" );
480 rFilterData
[ nPwdPos
].Value
<<= aPwd
;
485 if( nFilterNamePos
== -1 )
487 nFilterNamePos
= nAttribs
;
488 rFilterData
.realloc( ++nAttribs
);
489 rFilterData
[ nFilterNamePos
].Name
= OUString( "FilterName" );
492 const sal_Int32 nDocumentType
= 0; //const sal_Int32 nDocumentType = queryDocumentTypeDialog(m_xContext,aURL);
493 if( nDocumentType
< 0 )
497 else switch( nDocumentType
)
500 rFilterData
[nFilterNamePos
].Value
<<= OUString( "draw_pdf_import" );
504 rFilterData
[nFilterNamePos
].Value
<<= OUString( "impress_pdf_import" );
508 rFilterData
[nFilterNamePos
].Value
<<= OUString( "writer_pdf_import" );
512 OSL_FAIL("Unexpected case");
515 aOutTypeName
= OUString("pdf_Portable_Document_Format");
522 bool checkDocChecksum( const OUString
& rInPDFFileURL
,
524 const OUString
& rChkSum
)
527 if( rChkSum
.getLength() != 2* RTL_DIGEST_LENGTH_MD5
)
529 OSL_TRACE( "checksum of length %d, expected %d\n",
530 rChkSum
.getLength(), 2*RTL_DIGEST_LENGTH_MD5
);
534 // prepare checksum to test
535 sal_uInt8 nTestChecksum
[ RTL_DIGEST_LENGTH_MD5
];
536 const sal_Unicode
* pChar
= rChkSum
.getStr();
537 for( unsigned int i
= 0; i
< RTL_DIGEST_LENGTH_MD5
; i
++ )
539 sal_uInt8 nByte
= sal_uInt8( ( (*pChar
>= '0' && *pChar
<= '9') ? *pChar
- '0' :
540 ( (*pChar
>= 'A' && *pChar
<= 'F') ? *pChar
- 'A' + 10 :
541 ( (*pChar
>= 'a' && *pChar
<= 'f') ? *pChar
- 'a' + 10 :
545 nByte
|= ( (*pChar
>= '0' && *pChar
<= '9') ? *pChar
- '0' :
546 ( (*pChar
>= 'A' && *pChar
<= 'F') ? *pChar
- 'A' + 10 :
547 ( (*pChar
>= 'a' && *pChar
<= 'f') ? *pChar
- 'a' + 10 :
550 nTestChecksum
[i
] = nByte
;
553 // open file and calculate actual checksum up to index nBytes
554 sal_uInt8 nActualChecksum
[ RTL_DIGEST_LENGTH_MD5
];
555 memset( nActualChecksum
, 0, sizeof(nActualChecksum
) );
556 rtlDigest aActualDigest
= rtl_digest_createMD5();
557 oslFileHandle aRead
= NULL
;
558 oslFileError aErr
= osl_File_E_None
;
559 if( (aErr
= osl_openFile(rInPDFFileURL
.pData
,
561 osl_File_OpenFlag_Read
)) == osl_File_E_None
)
565 sal_uInt64 nBytesRead
= 0;
566 while( nCur
< nBytes
)
568 sal_uInt32 nPass
= (nBytes
- nCur
) > sizeof( aBuf
) ? sizeof( aBuf
) : nBytes
- nCur
;
569 if( (aErr
= osl_readFile( aRead
, aBuf
, nPass
, &nBytesRead
)) != osl_File_E_None
574 nPass
= static_cast<sal_uInt32
>(nBytesRead
);
576 rtl_digest_updateMD5( aActualDigest
, aBuf
, nPass
);
578 rtl_digest_getMD5( aActualDigest
, nActualChecksum
, sizeof(nActualChecksum
) );
579 osl_closeFile( aRead
);
581 rtl_digest_destroyMD5( aActualDigest
);
583 // compare the contents
584 bRet
= (0 == memcmp( nActualChecksum
, nTestChecksum
, sizeof( nActualChecksum
) ));
585 #if OSL_DEBUG_LEVEL > 1
586 OSL_TRACE( "test checksum: " );
587 for( unsigned int i
= 0; i
< sizeof(nTestChecksum
); i
++ )
588 OSL_TRACE( "%.2X", int(nTestChecksum
[i
]) );
590 OSL_TRACE( "file checksum: " );
591 for( unsigned int i
= 0; i
< sizeof(nActualChecksum
); i
++ )
592 OSL_TRACE( "%.2X", int(nActualChecksum
[i
]) );
598 uno::Reference
< io::XStream
> getAdditionalStream( const OUString
& rInPDFFileURL
,
599 OUString
& rOutMimetype
,
601 const uno::Reference
<uno::XComponentContext
>& xContext
,
602 const uno::Sequence
<beans::PropertyValue
>& rFilterData
,
605 uno::Reference
< io::XStream
> xEmbed
;
608 if( osl_getSystemPathFromFileURL( rInPDFFileURL
.pData
, &aSysUPath
.pData
) != osl_File_E_None
)
610 aPDFFile
= OUStringToOString( aSysUPath
, osl_getThreadTextEncoding() );
612 pdfparse::PDFReader aParser
;
613 boost::scoped_ptr
<pdfparse::PDFEntry
> pEntry( aParser
.read( aPDFFile
.getStr() ));
616 pdfparse::PDFFile
* pPDFFile
= dynamic_cast<pdfparse::PDFFile
*>(pEntry
.get());
619 unsigned int nElements
= pPDFFile
->m_aSubElements
.size();
620 while( nElements
-- > 0 )
622 pdfparse::PDFTrailer
* pTrailer
= dynamic_cast<pdfparse::PDFTrailer
*>(pPDFFile
->m_aSubElements
[nElements
]);
623 if( pTrailer
&& pTrailer
->m_pDict
)
625 // search document checksum entry
626 boost::unordered_map
< OString
,
628 OStringHash
>::iterator chk
;
629 chk
= pTrailer
->m_pDict
->m_aMap
.find( "DocChecksum" );
630 if( chk
== pTrailer
->m_pDict
->m_aMap
.end() )
632 OSL_TRACE( "no DocChecksum entry" );
635 pdfparse::PDFName
* pChkSumName
= dynamic_cast<pdfparse::PDFName
*>(chk
->second
);
636 if( pChkSumName
== NULL
)
638 OSL_TRACE( "no name for DocChecksum entry" );
642 // search for AdditionalStreams entry
643 boost::unordered_map
< OString
,
645 OStringHash
>::iterator add_stream
;
646 add_stream
= pTrailer
->m_pDict
->m_aMap
.find( "AdditionalStreams" );
647 if( add_stream
== pTrailer
->m_pDict
->m_aMap
.end() )
649 OSL_TRACE( "no AdditionalStreams entry" );
652 pdfparse::PDFArray
* pStreams
= dynamic_cast<pdfparse::PDFArray
*>(add_stream
->second
);
653 if( ! pStreams
|| pStreams
->m_aSubElements
.size() < 2 )
655 OSL_TRACE( "AdditionalStreams array too small" );
660 OUString aChkSum
= pChkSumName
->getFilteredName();
661 if( ! checkDocChecksum( rInPDFFileURL
, pTrailer
->m_nOffset
, aChkSum
) )
664 // extract addstream and mimetype
665 pdfparse::PDFName
* pMimeType
= dynamic_cast<pdfparse::PDFName
*>(pStreams
->m_aSubElements
[0]);
666 pdfparse::PDFObjectRef
* pStreamRef
= dynamic_cast<pdfparse::PDFObjectRef
*>(pStreams
->m_aSubElements
[1]);
668 OSL_ENSURE( pMimeType
, "error: no mimetype element\n" );
669 OSL_ENSURE( pStreamRef
, "error: no stream ref element\n" );
671 if( pMimeType
&& pStreamRef
)
673 pdfparse::PDFObject
* pObject
= pPDFFile
->findObject( pStreamRef
->m_nNumber
, pStreamRef
->m_nGeneration
);
674 OSL_ENSURE( pObject
, "object not found\n" );
677 if( pPDFFile
->isEncrypted() )
679 bool bAuthenticated
= false;
680 if( !io_rPwd
.isEmpty() )
682 OString aIsoPwd
= OUStringToOString( io_rPwd
,
683 RTL_TEXTENCODING_ISO_8859_1
);
684 bAuthenticated
= pPDFFile
->setupDecryptionData( aIsoPwd
.getStr() );
686 if( ! bAuthenticated
)
688 const beans::PropertyValue
* pAttribs
= rFilterData
.getConstArray();
689 sal_Int32 nAttribs
= rFilterData
.getLength();
690 uno::Reference
< task::XInteractionHandler
> xIntHdl
;
691 for( sal_Int32 i
= 0; i
< nAttribs
; i
++ )
693 if ( pAttribs
[i
].Name
== "InteractionHandler" )
694 pAttribs
[i
].Value
>>= xIntHdl
;
696 if( ! bMayUseUI
|| ! xIntHdl
.is() )
698 rOutMimetype
= pMimeType
->getFilteredName();
703 OUString
aDocName( rInPDFFileURL
.copy( rInPDFFileURL
.lastIndexOf( sal_Unicode('/') )+1 ) );
705 bool bEntered
= false;
708 bEntered
= getPassword( xIntHdl
, io_rPwd
, ! bEntered
, aDocName
);
709 OString aIsoPwd
= OUStringToOString( io_rPwd
,
710 RTL_TEXTENCODING_ISO_8859_1
);
711 bAuthenticated
= pPDFFile
->setupDecryptionData( aIsoPwd
.getStr() );
712 } while( bEntered
&& ! bAuthenticated
);
715 OSL_TRACE( "password: %s", bAuthenticated
? "matches" : "does not match" );
716 if( ! bAuthenticated
)
719 rOutMimetype
= pMimeType
->getFilteredName();
720 FileEmitContext
aContext( rInPDFFileURL
,
723 aContext
.m_bDecrypt
= pPDFFile
->isEncrypted();
724 pObject
->writeStream( aContext
, pPDFFile
);
725 xEmbed
= aContext
.getContextStream();
734 OSL_TRACE( "extracted add stream: mimetype %s\n",
735 OUStringToOString( rOutMimetype
,
736 RTL_TEXTENCODING_UTF8
).getStr());
742 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */