summaryrefslogtreecommitdiff
path: root/sdext/source/pdfimport/filterdet.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sdext/source/pdfimport/filterdet.cxx')
-rw-r--r--sdext/source/pdfimport/filterdet.cxx757
1 files changed, 0 insertions, 757 deletions
diff --git a/sdext/source/pdfimport/filterdet.cxx b/sdext/source/pdfimport/filterdet.cxx
deleted file mode 100644
index c83919c..0000000
--- a/sdext/source/pdfimport/filterdet.cxx
+++ /dev/null
@@ -1,757 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_sdext.hxx"
-
-#include "filterdet.hxx"
-#include "inc/pdfparse.hxx"
-
-#include <osl/diagnose.h>
-#include <osl/file.h>
-#include <osl/thread.h>
-#include <rtl/digest.h>
-#include <rtl/ref.hxx>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/awt/XWindow.hpp>
-#include <com/sun/star/awt/XListBox.hpp>
-#include <com/sun/star/awt/XDialogEventHandler.hpp>
-#include <com/sun/star/awt/XDialogProvider2.hpp>
-#include <com/sun/star/awt/XControlContainer.hpp>
-#include <com/sun/star/uno/RuntimeException.hpp>
-#include <com/sun/star/io/XInputStream.hpp>
-#include <com/sun/star/io/XStream.hpp>
-#include <com/sun/star/io/XSeekable.hpp>
-
-#include <boost/scoped_ptr.hpp>
-
-using namespace com::sun::star;
-
-namespace pdfi
-{
-
-// TODO(T3): locking/thread safety
-
-namespace {
- typedef ::cppu::WeakComponentImplHelper1<
- com::sun::star::awt::XDialogEventHandler > ChooserDialogHandlerBase;
- class ChooserDialogHandler : private cppu::BaseMutex,
- public ChooserDialogHandlerBase
- {
- uno::Reference<awt::XListBox> m_xListbox;
- uno::Reference<awt::XWindow> m_xWriterText;
- uno::Reference<awt::XWindow> m_xDrawText;
- uno::Reference<awt::XWindow> m_xImpressText;
-
- enum{ DRAW_INDEX=0, IMPRESS_INDEX=1, WRITER_INDEX=2 };
- void selectionChanged( sal_Int32 nIndex ) const
- {
- sal_Bool bWriterState(sal_False);
- sal_Bool bDrawState(sal_False);
- sal_Bool bImpressState(sal_False);
- switch(nIndex)
- {
- default:
- OSL_FAIL("Unexpected case!");
- break;
- case DRAW_INDEX:
- bDrawState=sal_True;
- break;
- case IMPRESS_INDEX:
- bImpressState=sal_True;
- break;
- case WRITER_INDEX:
- bWriterState=sal_True;
- break;
- }
- m_xWriterText->setVisible(bWriterState);
- m_xDrawText->setVisible(bDrawState);
- m_xImpressText->setVisible(bImpressState);
- }
- public:
- ChooserDialogHandler() :
- ChooserDialogHandlerBase(m_aMutex),
- m_xListbox(),
- m_xWriterText(),
- m_xDrawText(),
- m_xImpressText()
- {}
-
- void initControls( const uno::Reference<awt::XControlContainer>& xControls,
- const rtl::OUString& rFilename )
- {
- m_xListbox.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListBox" ))),
- uno::UNO_QUERY_THROW );
- m_xWriterText.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InfoWriter" ))),
- uno::UNO_QUERY_THROW );
- m_xImpressText.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InfoImpress" ))),
- uno::UNO_QUERY_THROW );
- m_xDrawText.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InfoDraw" ))),
- uno::UNO_QUERY_THROW );
-
- uno::Reference<awt::XWindow> xControl;
- xControl.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListBoxWriter" ))),
- uno::UNO_QUERY_THROW );
- xControl->setVisible(sal_False);
- xControl.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListBoxImpress" ))),
- uno::UNO_QUERY_THROW );
- xControl->setVisible(sal_False);
- xControl.set(xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ListBoxDraw" ))),
- uno::UNO_QUERY_THROW );
- xControl->setVisible(sal_False);
- uno::Reference<beans::XPropertySet> xPropSet(
- xControls->getControl(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ComboLabel" )))->getModel(),
- uno::UNO_QUERY_THROW );
- rtl::OUString aFilename( rFilename.copy(rFilename.lastIndexOf('/')+1) );
- rtl::OUString aLabel;
- xPropSet->getPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Label" ))) >>= aLabel;
- const char pFileName[] = "%FILENAME";
- aLabel = aLabel.replaceAt(
- aLabel.indexOfAsciiL(pFileName,sizeof(pFileName)/sizeof(*pFileName)-1),
- sizeof(pFileName)/sizeof(*pFileName)-1,
- aFilename );
- xPropSet->setPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Label" )),
- uno::makeAny(aLabel));
-
- uno::Sequence<rtl::OUString> aListboxItems(3);
- aListboxItems[DRAW_INDEX] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Drawing" ));
- aListboxItems[IMPRESS_INDEX] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Presentation" ));
- aListboxItems[WRITER_INDEX] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Text Document" ));
-
- m_xListbox->addItems(aListboxItems,0);
- m_xListbox->selectItemPos(0,sal_True);
- selectionChanged(0);
- }
-
- sal_Int32 getSelectedItem() const
- {
- return m_xListbox->getSelectedItemPos();
- }
-
- virtual ::sal_Bool SAL_CALL callHandlerMethod( const uno::Reference< awt::XDialog >& /*xDialog*/,
- const uno::Any& /*EventObject*/,
- const ::rtl::OUString& MethodName ) throw (lang::WrappedTargetException, uno::RuntimeException)
- {
- (void)MethodName;
- OSL_ENSURE( MethodName.compareToAscii("SelectionChanged") == 0,
- "Invalid event name" );
- selectionChanged(getSelectedItem());
- return sal_True;
- }
-
- virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedMethodNames( ) throw (uno::RuntimeException)
- {
- uno::Sequence< ::rtl::OUString > aMethods(1);
- aMethods[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectionChanged" ));
- return aMethods;
- }
- };
-}
-
-class FileEmitContext : public pdfparse::EmitContext
-{
-private:
- oslFileHandle m_aReadHandle;
- unsigned int m_nReadLen;
- uno::Reference< io::XStream > m_xContextStream;
- uno::Reference< io::XSeekable > m_xSeek;
- uno::Reference< io::XOutputStream > m_xOut;
-
-public:
- FileEmitContext( const rtl::OUString& rOrigFile,
- const uno::Reference< uno::XComponentContext >& xContext,
- const pdfparse::PDFContainer* pTop );
- virtual ~FileEmitContext();
-
- virtual bool write( const void* pBuf, unsigned int nLen );
- virtual unsigned int getCurPos();
- virtual bool copyOrigBytes( unsigned int nOrigOffset, unsigned int nLen );
- virtual unsigned int readOrigBytes( unsigned int nOrigOffset, unsigned int nLen, void* pBuf );
-
- const uno::Reference< io::XStream >& getContextStream() const { return m_xContextStream; }
-};
-
-FileEmitContext::FileEmitContext( const rtl::OUString& rOrigFile,
- const uno::Reference< uno::XComponentContext >& xContext,
- const pdfparse::PDFContainer* pTop ) :
- pdfparse::EmitContext( pTop ),
- m_aReadHandle(NULL),
- m_nReadLen(0),
- m_xContextStream(),
- m_xSeek(),
- m_xOut()
-{
- m_xContextStream = uno::Reference< io::XStream >(
- xContext->getServiceManager()->createInstanceWithContext(
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ),
- xContext ), uno::UNO_QUERY_THROW );
- m_xOut = m_xContextStream->getOutputStream();
- m_xSeek = uno::Reference<io::XSeekable>(m_xOut, uno::UNO_QUERY_THROW );
-
- oslFileError aErr = osl_File_E_None;
- if( (aErr=osl_openFile( rOrigFile.pData,
- &m_aReadHandle,
- osl_File_OpenFlag_Read )) == osl_File_E_None )
- {
- if( (aErr=osl_setFilePos( m_aReadHandle,
- osl_Pos_End,
- 0 )) == osl_File_E_None )
- {
- sal_uInt64 nFileSize = 0;
- if( (aErr=osl_getFilePos( m_aReadHandle,
- &nFileSize )) == osl_File_E_None )
- {
- m_nReadLen = static_cast<unsigned int>(nFileSize);
- }
- }
- if( aErr != osl_File_E_None )
- {
- osl_closeFile( m_aReadHandle );
- m_aReadHandle = NULL;
- }
- }
- m_bDeflate = true;
-}
-
-FileEmitContext::~FileEmitContext()
-{
- if( m_aReadHandle )
- osl_closeFile( m_aReadHandle );
-}
-
-bool FileEmitContext::write( const void* pBuf, unsigned int nLen )
-{
- if( ! m_xOut.is() )
- return false;
-
- uno::Sequence< sal_Int8 > aSeq( nLen );
- rtl_copyMemory( aSeq.getArray(), pBuf, nLen );
- m_xOut->writeBytes( aSeq );
- return true;
-}
-
-unsigned int FileEmitContext::getCurPos()
-{
- unsigned int nPos = 0;
- if( m_xSeek.is() )
- {
- nPos = static_cast<unsigned int>( m_xSeek->getPosition() );
- }
- return nPos;
-}
-
-bool FileEmitContext::copyOrigBytes( unsigned int nOrigOffset, unsigned int nLen )
-{
- if( nOrigOffset + nLen > m_nReadLen )
- return false;
-
- if( osl_setFilePos( m_aReadHandle, osl_Pos_Absolut, nOrigOffset ) != osl_File_E_None )
- return false;
-
- uno::Sequence< sal_Int8 > aSeq( nLen );
-
- sal_uInt64 nBytesRead = 0;
- if( osl_readFile( m_aReadHandle,
- aSeq.getArray(),
- nLen,
- &nBytesRead ) != osl_File_E_None
- || nBytesRead != static_cast<sal_uInt64>(nLen) )
- {
- return false;
- }
-
- m_xOut->writeBytes( aSeq );
- return true;
-}
-
-unsigned int FileEmitContext::readOrigBytes( unsigned int nOrigOffset, unsigned int nLen, void* pBuf )
-{
- if( nOrigOffset + nLen > m_nReadLen )
- return 0;
-
- if( osl_setFilePos( m_aReadHandle,
- osl_Pos_Absolut,
- nOrigOffset ) != osl_File_E_None )
- {
- return 0;
- }
-
- sal_uInt64 nBytesRead = 0;
- if( osl_readFile( m_aReadHandle,
- pBuf,
- nLen,
- &nBytesRead ) != osl_File_E_None )
- {
- return 0;
- }
- return static_cast<unsigned int>(nBytesRead);
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
-
-
-PDFDetector::PDFDetector( const uno::Reference< uno::XComponentContext >& xContext) :
- PDFDetectorBase( m_aMutex ),
- m_xContext( xContext )
-{}
-
-// XExtendedFilterDetection
-rtl::OUString SAL_CALL PDFDetector::detect( uno::Sequence< beans::PropertyValue >& rFilterData ) throw( uno::RuntimeException )
-{
- osl::MutexGuard const guard( m_aMutex );
- bool bSuccess = false;
-
- // get the InputStream carrying the PDF content
- uno::Reference< io::XInputStream > xInput;
- uno::Reference< io::XStream > xEmbedStream;
- rtl::OUString aOutFilterName, aOutTypeName;
- rtl::OUString aURL;
- rtl::OUString aPwd;
- const beans::PropertyValue* pAttribs = rFilterData.getConstArray();
- sal_Int32 nAttribs = rFilterData.getLength();
- sal_Int32 nFilterNamePos = -1;
- sal_Int32 nPwdPos = -1;
- for( sal_Int32 i = 0; i < nAttribs; i++ )
- {
-#if OSL_DEBUG_LEVEL > 1
- rtl::OUString aVal( RTL_CONSTASCII_USTRINGPARAM( "<no string>" ) );
- pAttribs[i].Value >>= aVal;
- OSL_TRACE( "doDetection: Attrib: %s = %s\n",
- rtl::OUStringToOString( pAttribs[i].Name, RTL_TEXTENCODING_UTF8 ).getStr(),
- rtl::OUStringToOString( aVal, RTL_TEXTENCODING_UTF8 ).getStr() );
-#endif
- if( pAttribs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "InputStream" ) ) )
- pAttribs[i].Value >>= xInput;
- else if( pAttribs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "URL" ) ) )
- pAttribs[i].Value >>= aURL;
- else if( pAttribs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) )
- nFilterNamePos = i;
- else if( pAttribs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Password" ) ) )
- {
- nPwdPos = i;
- pAttribs[i].Value >>= aPwd;
- }
- }
- if( xInput.is() )
- {
- uno::Reference< io::XSeekable > xSeek( xInput, uno::UNO_QUERY );
- if( xSeek.is() )
- xSeek->seek( 0 );
- // read the first 1024 byte (see PDF reference implementation note 12)
- const sal_Int32 nHeaderSize = 1024;
- uno::Sequence< sal_Int8 > aBuf( nHeaderSize );
- sal_uInt64 nBytes = 0;
- nBytes = xInput->readBytes( aBuf, nHeaderSize );
- if( nBytes > 5 )
- {
- const sal_Int8* pBytes = aBuf.getConstArray();
- for( unsigned int i = 0; i < nBytes-5; i++ )
- {
- if( pBytes[i] == '%' &&
- pBytes[i+1] == 'P' &&
- pBytes[i+2] == 'D' &&
- pBytes[i+3] == 'F' &&
- pBytes[i+4] == '-' )
- {
- bSuccess = true;
- break;
- }
- }
- }
-
- // check for hybrid PDF
- oslFileHandle aFile = NULL;
- if( bSuccess &&
- ( aURL.getLength() == 0 || aURL.compareToAscii( "file:", 5 ) != 0 )
- )
- {
- sal_uInt64 nWritten = 0;
- if( osl_createTempFile( NULL, &aFile, &aURL.pData ) != osl_File_E_None )
- {
- bSuccess = false;
- }
- else
- {
-#if OSL_DEBUG_LEVEL > 1
- OSL_TRACE( "created temp file %s\n",
- rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr() );
-#endif
- osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten );
-
- OSL_ENSURE( nWritten == nBytes, "writing of header bytes failed" );
-
- if( nWritten == nBytes )
- {
- const sal_uInt32 nBufSize = 4096;
- aBuf = uno::Sequence<sal_Int8>(nBufSize);
- // copy the bytes
- do
- {
- nBytes = xInput->readBytes( aBuf, nBufSize );
- if( nBytes > 0 )
- {
- osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten );
- if( nWritten != nBytes )
- {
- bSuccess = false;
- break;
- }
- }
- } while( nBytes == nBufSize );
- }
- }
- osl_closeFile( aFile );
- }
- rtl::OUString aEmbedMimetype;
- xEmbedStream = getAdditionalStream( aURL, aEmbedMimetype, aPwd, m_xContext, rFilterData, false );
- if( aFile )
- osl_removeFile( aURL.pData );
- if( aEmbedMimetype.getLength() )
- {
- if( aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.text" ) )
- || aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.text-master" ) ) )
- aOutFilterName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer_pdf_addstream_import" ) );
- else if( aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.presentation" ) ) )
- aOutFilterName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress_pdf_addstream_import" ) );
- else if( aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.graphics" ) )
- || aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.drawing" ) ) )
- aOutFilterName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw_pdf_addstream_import" ) );
- else if( aEmbedMimetype.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "application/vnd.oasis.opendocument.spreadsheet" ) ) )
- aOutFilterName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc_pdf_addstream_import" ) );
- }
- }
-
- if( bSuccess )
- {
- if( aOutFilterName.getLength() )
- {
- if( nFilterNamePos == -1 )
- {
- nFilterNamePos = nAttribs;
- rFilterData.realloc( ++nAttribs );
- rFilterData[ nFilterNamePos ].Name =
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
- }
- aOutTypeName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("pdf_Portable_Document_Format") );
-
- OSL_TRACE( "setting filter name %s, input stream %s\n",
- rtl::OUStringToOString( aOutFilterName, RTL_TEXTENCODING_UTF8 ).getStr(),
- xEmbedStream.is() ? "present" : "not present" );
-
- rFilterData[nFilterNamePos].Value <<= aOutFilterName;
- if( xEmbedStream.is() )
- {
- rFilterData.realloc( ++nAttribs );
- rFilterData[nAttribs-1].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "EmbeddedSubstream" ) );
- rFilterData[nAttribs-1].Value <<= xEmbedStream;
- }
- if( aPwd.getLength() )
- {
- if( nPwdPos == -1 )
- {
- nPwdPos = nAttribs;
- rFilterData.realloc( ++nAttribs );
- rFilterData[ nPwdPos ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Password" ) );
- }
- rFilterData[ nPwdPos ].Value <<= aPwd;
- }
- }
- else
- {
- if( nFilterNamePos == -1 )
- {
- nFilterNamePos = nAttribs;
- rFilterData.realloc( ++nAttribs );
- rFilterData[ nFilterNamePos ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
- }
-
- const sal_Int32 nDocumentType = 0; //const sal_Int32 nDocumentType = queryDocumentTypeDialog(m_xContext,aURL);
- if( nDocumentType < 0 )
- {
- return rtl::OUString();
- }
- else switch( nDocumentType )
- {
- case 0:
- rFilterData[nFilterNamePos].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw_pdf_import" ) );
- break;
-
- case 1:
- rFilterData[nFilterNamePos].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress_pdf_import" ) );
- break;
-
- case 2:
- rFilterData[nFilterNamePos].Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer_pdf_import" ) );
- break;
-
- default:
- OSL_FAIL("Unexpected case");
- }
-
- aOutTypeName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("pdf_Portable_Document_Format") );
- }
- }
-
- return aOutTypeName;
-}
-
-bool checkDocChecksum( const rtl::OUString& rInPDFFileURL,
- sal_uInt32 nBytes,
- const rtl::OUString& rChkSum )
-{
- bool bRet = false;
- if( rChkSum.getLength() != 2* RTL_DIGEST_LENGTH_MD5 )
- {
- OSL_TRACE( "checksum of length %d, expected %d\n",
- rChkSum.getLength(), 2*RTL_DIGEST_LENGTH_MD5 );
- return false;
- }
-
- // prepare checksum to test
- sal_uInt8 nTestChecksum[ RTL_DIGEST_LENGTH_MD5 ];
- const sal_Unicode* pChar = rChkSum.getStr();
- for( unsigned int i = 0; i < RTL_DIGEST_LENGTH_MD5; i++ )
- {
- sal_uInt8 nByte = sal_uInt8( ( (*pChar >= '0' && *pChar <= '9') ? *pChar - '0' :
- ( (*pChar >= 'A' && *pChar <= 'F') ? *pChar - 'A' + 10 :
- ( (*pChar >= 'a' && *pChar <= 'f') ? *pChar - 'a' + 10 :
- 0 ) ) ) );
- nByte <<= 4;
- pChar++;
- nByte |= ( (*pChar >= '0' && *pChar <= '9') ? *pChar - '0' :
- ( (*pChar >= 'A' && *pChar <= 'F') ? *pChar - 'A' + 10 :
- ( (*pChar >= 'a' && *pChar <= 'f') ? *pChar - 'a' + 10 :
- 0 ) ) );
- pChar++;
- nTestChecksum[i] = nByte;
- }
-
- // open file and calculate actual checksum up to index nBytes
- sal_uInt8 nActualChecksum[ RTL_DIGEST_LENGTH_MD5 ];
- rtl_zeroMemory( nActualChecksum, sizeof(nActualChecksum) );
- rtlDigest aActualDigest = rtl_digest_createMD5();
- oslFileHandle aRead = NULL;
- oslFileError aErr = osl_File_E_None;
- if( (aErr = osl_openFile(rInPDFFileURL.pData,
- &aRead,
- osl_File_OpenFlag_Read )) == osl_File_E_None )
- {
- sal_Int8 aBuf[4096];
- sal_uInt32 nCur = 0;
- sal_uInt64 nBytesRead = 0;
- while( nCur < nBytes )
- {
- sal_uInt32 nPass = (nBytes - nCur) > sizeof( aBuf ) ? sizeof( aBuf ) : nBytes - nCur;
- if( (aErr = osl_readFile( aRead, aBuf, nPass, &nBytesRead)) != osl_File_E_None
- || nBytesRead == 0 )
- {
- break;
- }
- nPass = static_cast<sal_uInt32>(nBytesRead);
- nCur += nPass;
- rtl_digest_updateMD5( aActualDigest, aBuf, nPass );
- }
- rtl_digest_getMD5( aActualDigest, nActualChecksum, sizeof(nActualChecksum) );
- osl_closeFile( aRead );
- }
- rtl_digest_destroyMD5( aActualDigest );
-
- // compare the contents
- bRet = (0 == rtl_compareMemory( nActualChecksum, nTestChecksum, sizeof( nActualChecksum ) ));
-#if OSL_DEBUG_LEVEL > 1
- OSL_TRACE( "test checksum: " );
- for( unsigned int i = 0; i < sizeof(nTestChecksum); i++ )
- OSL_TRACE( "%.2X", int(nTestChecksum[i]) );
- OSL_TRACE( "\n" );
- OSL_TRACE( "file checksum: " );
- for( unsigned int i = 0; i < sizeof(nActualChecksum); i++ )
- OSL_TRACE( "%.2X", int(nActualChecksum[i]) );
- OSL_TRACE( "\n" );
-#endif
- return bRet;
-}
-
-uno::Reference< io::XStream > getAdditionalStream( const rtl::OUString& rInPDFFileURL,
- rtl::OUString& rOutMimetype,
- rtl::OUString& io_rPwd,
- const uno::Reference<uno::XComponentContext>& xContext,
- const uno::Sequence<beans::PropertyValue>& rFilterData,
- bool bMayUseUI )
-{
- uno::Reference< io::XStream > xEmbed;
- rtl::OString aPDFFile;
- rtl::OUString aSysUPath;
- if( osl_getSystemPathFromFileURL( rInPDFFileURL.pData, &aSysUPath.pData ) != osl_File_E_None )
- return xEmbed;
- aPDFFile = rtl::OUStringToOString( aSysUPath, osl_getThreadTextEncoding() );
-
- pdfparse::PDFReader aParser;
- boost::scoped_ptr<pdfparse::PDFEntry> pEntry( aParser.read( aPDFFile.getStr() ));
- if( pEntry )
- {
- pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get());
- if( pPDFFile )
- {
- unsigned int nElements = pPDFFile->m_aSubElements.size();
- while( nElements-- > 0 )
- {
- pdfparse::PDFTrailer* pTrailer = dynamic_cast<pdfparse::PDFTrailer*>(pPDFFile->m_aSubElements[nElements]);
- if( pTrailer && pTrailer->m_pDict )
- {
- // search document checksum entry
- boost::unordered_map< rtl::OString,
- pdfparse::PDFEntry*,
- rtl::OStringHash >::iterator chk;
- chk = pTrailer->m_pDict->m_aMap.find( "DocChecksum" );
- if( chk == pTrailer->m_pDict->m_aMap.end() )
- {
- OSL_TRACE( "no DocChecksum entry\n" );
- continue;
- }
- pdfparse::PDFName* pChkSumName = dynamic_cast<pdfparse::PDFName*>(chk->second);
- if( pChkSumName == NULL )
- {
- OSL_TRACE( "no name for DocChecksum entry\n" );
- continue;
- }
-
- // search for AdditionalStreams entry
- boost::unordered_map< rtl::OString,
- pdfparse::PDFEntry*,
- rtl::OStringHash >::iterator add_stream;
- add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams" );
- if( add_stream == pTrailer->m_pDict->m_aMap.end() )
- {
- OSL_TRACE( "no AdditionalStreams entry\n" );
- continue;
- }
- pdfparse::PDFArray* pStreams = dynamic_cast<pdfparse::PDFArray*>(add_stream->second);
- if( ! pStreams || pStreams->m_aSubElements.size() < 2 )
- {
- OSL_TRACE( "AdditionalStreams array too small\n" );
- continue;
- }
-
- // check checksum
- rtl::OUString aChkSum = pChkSumName->getFilteredName();
- if( ! checkDocChecksum( rInPDFFileURL, pTrailer->m_nOffset, aChkSum ) )
- continue;
-
- // extract addstream and mimetype
- pdfparse::PDFName* pMimeType = dynamic_cast<pdfparse::PDFName*>(pStreams->m_aSubElements[0]);
- pdfparse::PDFObjectRef* pStreamRef = dynamic_cast<pdfparse::PDFObjectRef*>(pStreams->m_aSubElements[1]);
-
- OSL_ENSURE( pMimeType, "error: no mimetype element\n" );
- OSL_ENSURE( pStreamRef, "error: no stream ref element\n" );
-
- if( pMimeType && pStreamRef )
- {
- pdfparse::PDFObject* pObject = pPDFFile->findObject( pStreamRef->m_nNumber, pStreamRef->m_nGeneration );
- OSL_ENSURE( pObject, "object not found\n" );
- if( pObject )
- {
- if( pPDFFile->isEncrypted() )
- {
- bool bAuthenticated = false;
- if( io_rPwd.getLength() )
- {
- rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
- RTL_TEXTENCODING_ISO_8859_1 );
- bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
- // trash password string on heap
- rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
- }
- if( ! bAuthenticated )
- {
- const beans::PropertyValue* pAttribs = rFilterData.getConstArray();
- sal_Int32 nAttribs = rFilterData.getLength();
- uno::Reference< task::XInteractionHandler > xIntHdl;
- for( sal_Int32 i = 0; i < nAttribs; i++ )
- {
- if( pAttribs[i].Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ) ) )
- pAttribs[i].Value >>= xIntHdl;
- }
- if( ! bMayUseUI || ! xIntHdl.is() )
- {
- rOutMimetype = pMimeType->getFilteredName();
- xEmbed.clear();
- break;
- }
-
- rtl::OUString aDocName( rInPDFFileURL.copy( rInPDFFileURL.lastIndexOf( sal_Unicode('/') )+1 ) );
-
- bool bEntered = false;
- do
- {
- bEntered = getPassword( xIntHdl, io_rPwd, ! bEntered, aDocName );
- rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
- RTL_TEXTENCODING_ISO_8859_1 );
- bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
- // trash password string on heap
- rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
- } while( bEntered && ! bAuthenticated );
- }
-
- OSL_TRACE( "password: %s\n", bAuthenticated ? "matches" : "does not match" );
- if( ! bAuthenticated )
- continue;
- }
- rOutMimetype = pMimeType->getFilteredName();
- FileEmitContext aContext( rInPDFFileURL,
- xContext,
- pPDFFile );
- aContext.m_bDecrypt = pPDFFile->isEncrypted();
- pObject->writeStream( aContext, pPDFFile );
- xEmbed = aContext.getContextStream();
- break; // success
- }
- }
- }
- }
- }
- }
-
- OSL_TRACE( "extracted add stream: mimetype %s\n",
- rtl::OUStringToOString( rOutMimetype,
- RTL_TEXTENCODING_UTF8 ).getStr());
- return xEmbed;
-}
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */