/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"

#include <pdfparse.hxx>

#include <rtl/strbuf.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/alloc.h>
#include <rtl/digest.h>
#include <rtl/cipher.h>
#include <rtl/memory.h>
#ifdef SYSTEM_ZLIB
#include "zlib.h"
#else
#include <zlib/zlib.h>
#endif

#include <math.h>
#include <map>

#include <stdio.h>

using namespace rtl;

namespace pdfparse
{

struct EmitImplData
{
    // xref table: maps object number to a pair of (generation, buffer offset)
    typedef std::map< unsigned int, std::pair< unsigned int, unsigned int > > XRefTable;
    XRefTable m_aXRefTable;
    // container of all indirect objects (usually a PDFFile*)
    const PDFContainer* m_pObjectContainer;
    unsigned int m_nDecryptObject;
    unsigned int m_nDecryptGeneration;
    
    // returns true if the xref table was updated
    bool insertXref( unsigned int nObject, unsigned int nGeneration, unsigned int nOffset )
    {
        XRefTable::iterator it = m_aXRefTable.find( nObject );
        if( it == m_aXRefTable.end() )
        {
            // new entry
            m_aXRefTable[ nObject ] = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
            return true;
        }
        // update old entry, if generation number is higher
        if( it->second.first < nGeneration )
        {
            it->second = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
            return true;
        }
        return false;
    }
    
    EmitImplData( const PDFContainer* pTopContainer ) :
        m_pObjectContainer( pTopContainer ),
        m_nDecryptObject( 0 ),
        m_nDecryptGeneration( 0 )
    {}
    ~EmitImplData() {}
    bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
                  unsigned int nObject, unsigned int nGeneration ) const
    {
        const PDFFile* pFile = dynamic_cast<const PDFFile*>(m_pObjectContainer);
        return pFile ? pFile->decrypt( pInBuffer, nLen, pOutBuffer, nObject, nGeneration ) : false;
    }
    
    void setDecryptObject( unsigned int nObject, unsigned int nGeneration )
    {
        m_nDecryptObject = nObject;
        m_nDecryptGeneration = nGeneration;
    }
};

}

using namespace pdfparse;

EmitContext::EmitContext( const PDFContainer* pTop ) :
    m_bDeflate( false ),
    m_bDecrypt( false ),
    m_pImplData( NULL )
{
    if( pTop )
        m_pImplData = new EmitImplData( pTop );
}

EmitContext::~EmitContext()
{
    delete m_pImplData;
}

PDFEntry::~PDFEntry()
{
}

EmitImplData* PDFEntry::getEmitData( EmitContext& rContext ) const
{
    return rContext.m_pImplData;
}

void PDFEntry::setEmitData( EmitContext& rContext, EmitImplData* pNewEmitData ) const
{
    if( rContext.m_pImplData && rContext.m_pImplData != pNewEmitData )
        delete rContext.m_pImplData;
    rContext.m_pImplData = pNewEmitData;
}

PDFValue::~PDFValue()
{
}

PDFComment::~PDFComment()
{
}

bool PDFComment::emit( EmitContext& rWriteContext ) const
{
    return rWriteContext.write( m_aComment.getStr(), m_aComment.getLength() );
}

PDFEntry* PDFComment::clone() const
{
    return new PDFComment( m_aComment );
}

PDFName::~PDFName()
{
}

bool PDFName::emit( EmitContext& rWriteContext ) const
{
    if( ! rWriteContext.write( " /", 2 ) )
        return false;
    return rWriteContext.write( m_aName.getStr(), m_aName.getLength() );
}

PDFEntry* PDFName::clone() const
{
    return new PDFName( m_aName );
}

OUString PDFName::getFilteredName() const
{
    OStringBuffer aFilter( m_aName.getLength() );
    const sal_Char* pStr = m_aName.getStr();
    unsigned int nLen = m_aName.getLength();
    for( unsigned int i = 0; i < nLen; i++ )
    {
        if( pStr[i] == '#' && i < nLen - 3 )
        {
            sal_Char rResult = 0;
            i++;
            if( pStr[i] >= '0' && pStr[i] <= '9' )
                rResult = sal_Char( pStr[i]-'0' ) << 4;
            else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
                rResult = sal_Char( pStr[i]-'a' + 10 ) << 4;
            else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
                rResult = sal_Char( pStr[i]-'A' + 10 ) << 4;
            i++;
            if( pStr[i] >= '0' && pStr[i] <= '9' )
                rResult |= sal_Char( pStr[i]-'0' );
            else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
                rResult |= sal_Char( pStr[i]-'a' + 10 );
            else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
                rResult |= sal_Char( pStr[i]-'A' + 10 );
            aFilter.append( rResult );
        }
        else
            aFilter.append( pStr[i] );
    }
    return OStringToOUString( aFilter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
}

PDFString::~PDFString()
{
}

bool PDFString::emit( EmitContext& rWriteContext ) const
{
    if( ! rWriteContext.write( " ", 1 ) )
        return false;
    EmitImplData* pEData = getEmitData( rWriteContext );
    if( rWriteContext.m_bDecrypt && pEData && pEData->m_nDecryptObject )
    {
        OString aFiltered( getFilteredString() );
        // decrypt inplace (evil since OString is supposed to be const
        // however in this case we know that getFilteredString returned a singular string instance
        pEData->decrypt( (sal_uInt8*)aFiltered.getStr(), aFiltered.getLength(),
                         (sal_uInt8*)aFiltered.getStr(),
                         pEData->m_nDecryptObject, pEData->m_nDecryptGeneration );
        // check for string or hex string
        const sal_Char* pStr = aFiltered.getStr();
        if( aFiltered.getLength() > 1 &&
           ( (pStr[0] == sal_Char(0xff) && pStr[1] == sal_Char(0xfe)) ||
             (pStr[0] == sal_Char(0xfe) && pStr[1] == sal_Char(0xff)) ) )
        {
            static const char pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                              '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            if( ! rWriteContext.write( "<", 1 ) )
                return false;
            for( sal_Int32 i = 0; i < aFiltered.getLength(); i++ )
            {
                if( ! rWriteContext.write( pHexTab + ((sal_uInt32(pStr[i]) >> 4) & 0x0f), 1 ) )
                    return false;
                if( ! rWriteContext.write( pHexTab + (sal_uInt32(pStr[i]) & 0x0f), 1 ) )
                    return false;
            }
            if( ! rWriteContext.write( ">", 1 ) )
                return false;
        }
        else
        {
            if( ! rWriteContext.write( "(", 1 ) )
                return false;
            if( ! rWriteContext.write( aFiltered.getStr(), aFiltered.getLength() ) )
                return false;
            if( ! rWriteContext.write( ")", 1 ) )
                return false;
        }
        return true;
    }
    return rWriteContext.write( m_aString.getStr(), m_aString.getLength() );
}

PDFEntry* PDFString::clone() const
{
    return new PDFString( m_aString );
}

OString PDFString::getFilteredString() const
{
    int nLen = m_aString.getLength();
    OStringBuffer aBuf( nLen );
    
    const sal_Char* pStr = m_aString.getStr();
    if( *pStr == '(' )
    {
        const sal_Char* pRun = pStr+1;
        while( pRun - pStr < nLen-1 )
        {
            if( *pRun == '\\' )
            {
                pRun++;
                if( pRun - pStr < nLen )
                {
                    sal_Char aEsc = 0;
                    if( *pRun == 'n' )
                        aEsc = '\n';
                    else if( *pRun == 'r' )
                        aEsc = '\r';
                    else if( *pRun == 't' )
                        aEsc = '\t';
                    else if( *pRun == 'b' )
                        aEsc = '\b';
                    else if( *pRun == 'f' )
                        aEsc = '\f';
                    else if( *pRun == '(' )
                        aEsc = '(';
                    else if( *pRun == ')' )
                        aEsc = ')';
                    else if( *pRun == '\\' )
                        aEsc = '\\';
                    else if( *pRun == '\n' )
                    {
                        pRun++;
                        continue;
                    }
                    else if( *pRun == '\r' )
                    {
                        pRun++;
                        if( *pRun == '\n' )
                            pRun++;
                        continue;
                    }
                    else
                    {
                        int i = 0;
                        while( i++ < 3 && *pRun >= '0' && *pRun <= '7' )
                            aEsc = 8*aEsc + (*pRun++ - '0');
                        // move pointer back to last character of octal sequence
                        pRun--;
                    }
                    aBuf.append( aEsc );
                }
            }
            else
                aBuf.append( *pRun );
            // move pointer to next character
            pRun++;
        }
    }
    else if( *pStr == '<' )
    {
        const sal_Char* pRun = pStr+1;
        while( *pRun != '>' && pRun - pStr < nLen )
        {
            sal_Char rResult = 0;
            if( *pRun >= '0' && *pRun <= '9' )
                rResult = sal_Char( *pRun-'0' ) << 4;
            else if( *pRun >= 'a' && *pRun <= 'f' )
                rResult = sal_Char( *pRun-'a' + 10 ) << 4;
            else if( *pRun >= 'A' && *pRun <= 'F' )
                rResult = sal_Char( *pRun-'A' + 10 ) << 4;
            pRun++;
            if( *pRun != '>' && pRun - pStr < nLen )
            {
                if( *pRun >= '0' && *pRun <= '9' )
                    rResult |= sal_Char( *pRun-'0' );
                else if( *pRun >= 'a' && *pRun <= 'f' )
                    rResult |= sal_Char( *pRun-'a' + 10 );
                else if( *pRun >= 'A' && *pRun <= 'F' )
                    rResult |= sal_Char( *pRun-'A' + 10 );
            }
            pRun++;
            aBuf.append( rResult );
        }
    }
    
    return aBuf.makeStringAndClear();
}

PDFNumber::~PDFNumber()
{
}

bool PDFNumber::emit( EmitContext& rWriteContext ) const
{
    rtl::OStringBuffer aBuf( 32 );
    aBuf.append( ' ' );
    
    double fValue = m_fValue;
    bool bNeg = false;
    int nPrecision = 5;
    if( fValue < 0.0 )
    {
        bNeg = true;
        fValue=-fValue;
    }

    sal_Int64 nInt = (sal_Int64)fValue;
    fValue -= (double)nInt;
    // optimizing hardware may lead to a value of 1.0 after the subtraction
    if( fValue == 1.0 || log10( 1.0-fValue ) <= -nPrecision )
    {
        nInt++;
        fValue = 0.0;
    }
    sal_Int64 nFrac = 0;
    if( fValue )
    {
        fValue *= pow( 10.0, (double)nPrecision );
        nFrac = (sal_Int64)fValue;
    }
    if( bNeg && ( nInt || nFrac ) )
        aBuf.append( '-' );
    aBuf.append( nInt );
    if( nFrac )
    {
		int i;
        aBuf.append( '.' );
		sal_Int64 nBound = (sal_Int64)(pow( 10.0, nPrecision - 1.0 )+0.5);
		for ( i = 0; ( i < nPrecision ) && nFrac; i++ )
		{
			sal_Int64 nNumb = nFrac / nBound;
			nFrac -= nNumb * nBound;
			aBuf.append( nNumb );
			nBound /= 10;
		}
    }
    
    return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
}

PDFEntry* PDFNumber::clone() const
{
    return new PDFNumber( m_fValue );
}


PDFBool::~PDFBool()
{
}

bool PDFBool::emit( EmitContext& rWriteContext ) const
{
    return m_bValue ? rWriteContext.write( " true", 5 ) : rWriteContext.write( " false", 6 );
}

PDFEntry* PDFBool::clone() const
{
    return new PDFBool( m_bValue );
}

PDFNull::~PDFNull()
{
}

bool PDFNull::emit( EmitContext& rWriteContext ) const
{
    return rWriteContext.write( " null", 5 );
}

PDFEntry* PDFNull::clone() const
{
    return new PDFNull();
}


PDFObjectRef::~PDFObjectRef()
{
}

bool PDFObjectRef::emit( EmitContext& rWriteContext ) const
{
    OStringBuffer aBuf( 16 );
    aBuf.append( ' ' );
    aBuf.append( sal_Int32( m_nNumber ) );
    aBuf.append( ' ' );
    aBuf.append( sal_Int32( m_nGeneration ) );
    aBuf.append( " R", 2 );
    return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
}

PDFEntry* PDFObjectRef::clone() const
{
    return new PDFObjectRef( m_nNumber, m_nGeneration );
}

PDFContainer::~PDFContainer()
{
    int nEle = m_aSubElements.size();
    for( int i = 0; i < nEle; i++ )
        delete m_aSubElements[i];
}

bool PDFContainer::emitSubElements( EmitContext& rWriteContext ) const
{
    int nEle = m_aSubElements.size();
    for( int i = 0; i < nEle; i++ )
    {
        if( rWriteContext.m_bDecrypt )
        {
            const PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
            if( pName && pName->m_aName.equals( rtl::OString("Encrypt") ) )
            {
                i++;
                continue;
            }
        }
        if( ! m_aSubElements[i]->emit( rWriteContext ) )
            return false;
    }
    return true;
}

void PDFContainer::cloneSubElements( std::vector<PDFEntry*>& rNewSubElements ) const
{
    int nEle = m_aSubElements.size();
    for( int i = 0; i < nEle; i++ )
        rNewSubElements.push_back( m_aSubElements[i]->clone() );
}

PDFObject* PDFContainer::findObject( unsigned int nNumber, unsigned int nGeneration ) const
{
    unsigned int nEle = m_aSubElements.size();
    for( unsigned int i = 0; i < nEle; i++ )
    {
        PDFObject* pObject = dynamic_cast<PDFObject*>(m_aSubElements[i]);
        if( pObject &&
            pObject->m_nNumber == nNumber &&
            pObject->m_nGeneration == nGeneration )
        {
            return pObject;
        }
    }
    return NULL;
}

PDFArray::~PDFArray()
{
}

bool PDFArray::emit( EmitContext& rWriteContext ) const
{
    if( ! rWriteContext.write( "[", 1 ) )
        return false;
    if( ! emitSubElements( rWriteContext ) )
        return false;
    return rWriteContext.write( "]", 1 );
}

PDFEntry* PDFArray::clone() const
{
    PDFArray* pNewAr = new PDFArray();
    cloneSubElements( pNewAr->m_aSubElements );
    return pNewAr;
}

PDFDict::~PDFDict()
{
}

bool PDFDict::emit( EmitContext& rWriteContext ) const
{
    if( ! rWriteContext.write( "<<\n", 3 ) )
        return false;
    if( ! emitSubElements( rWriteContext ) )
        return false;
    return rWriteContext.write( "\n>>\n", 4 );
}

void PDFDict::insertValue( const OString& rName, PDFEntry* pValue )
{
    if( ! pValue )
        eraseValue( rName );
    
    std::hash_map<OString,PDFEntry*,OStringHash>::iterator it = m_aMap.find( rName );
    if( it == m_aMap.end() )
    {
        // new name/value, pair, append it
        m_aSubElements.push_back( new PDFName( rName ) );
        m_aSubElements.push_back( pValue );
    }
    else
    {
        unsigned int nSub = m_aSubElements.size();
        for( unsigned int i = 0; i < nSub; i++ )
            if( m_aSubElements[i] == it->second )
                m_aSubElements[i] = pValue;
        delete it->second;
    }
    m_aMap[ rName ] = pValue;
}

void PDFDict::eraseValue( const OString& rName )
{
    unsigned int nEle = m_aSubElements.size();
    for( unsigned int i = 0; i < nEle; i++ )
    {
        PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
        if( pName && pName->m_aName.equals( rName ) )
        {
            for( unsigned int j = i+1; j < nEle; j++ )
            {
                if( dynamic_cast<PDFComment*>(m_aSubElements[j]) == NULL )
                {
                    // free name and value
                    delete m_aSubElements[j];
                    delete m_aSubElements[i];
                    // remove subelements from vector
                    m_aSubElements.erase( m_aSubElements.begin()+j );
                    m_aSubElements.erase( m_aSubElements.begin()+i );
                    buildMap();
                    return;
                }
            }
        }
    }
}

PDFEntry* PDFDict::buildMap()
{
    // clear map
    m_aMap.clear();
    // build map
    unsigned int nEle = m_aSubElements.size();
    PDFName* pName = NULL;
    for( unsigned int i = 0; i < nEle; i++ )
    {
        if( dynamic_cast<PDFComment*>(m_aSubElements[i]) == NULL )
        {
            if( pName )
            {
                m_aMap[ pName->m_aName ] = m_aSubElements[i];
                pName = NULL;
            }
            else if( (pName = dynamic_cast<PDFName*>(m_aSubElements[i])) == NULL )
                return m_aSubElements[i];
        }
    }
    return pName;
}

PDFEntry* PDFDict::clone() const
{
    PDFDict* pNewDict = new PDFDict();
    cloneSubElements( pNewDict->m_aSubElements );
    pNewDict->buildMap();
    return pNewDict;
}

PDFStream::~PDFStream()
{
}

bool PDFStream::emit( EmitContext& rWriteContext ) const
{
    return rWriteContext.copyOrigBytes( m_nBeginOffset, m_nEndOffset-m_nBeginOffset );
}

PDFEntry* PDFStream::clone() const
{
    return new PDFStream( m_nBeginOffset, m_nEndOffset, NULL );
}

unsigned int PDFStream::getDictLength( const PDFContainer* pContainer ) const
{
    if( ! m_pDict )
        return 0;
    // find /Length entry, can either be a direct or indirect number object
    std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
        m_pDict->m_aMap.find( "Length" );
    if( it == m_pDict->m_aMap.end() )
        return 0;
    PDFNumber* pNum = dynamic_cast<PDFNumber*>(it->second);
    if( ! pNum && pContainer )
    {
        PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(it->second);
        if( pRef )
        {
            int nEle = pContainer->m_aSubElements.size();
            for( int i = 0; i < nEle && ! pNum; i++ )
            {
                PDFObject* pObj = dynamic_cast<PDFObject*>(pContainer->m_aSubElements[i]);
                if( pObj &&
                    pObj->m_nNumber == pRef->m_nNumber &&
                    pObj->m_nGeneration == pRef->m_nGeneration )
                {
                    if( pObj->m_pObject )
                        pNum = dynamic_cast<PDFNumber*>(pObj->m_pObject);
                    break;
                }
            }
        }
    }
    return pNum ? static_cast<unsigned int>(pNum->m_fValue) : 0;
}

PDFObject::~PDFObject()
{
}

bool PDFObject::getDeflatedStream( char** ppStream, unsigned int* pBytes, const PDFContainer* pObjectContainer, EmitContext& rContext ) const
{
    bool bIsDeflated = false;
    if( m_pStream && m_pStream->m_pDict &&
        m_pStream->m_nEndOffset > m_pStream->m_nBeginOffset+15
        )
    {
        unsigned int nOuterStreamLen = m_pStream->m_nEndOffset - m_pStream->m_nBeginOffset;
        *ppStream = static_cast<char*>(rtl_allocateMemory( nOuterStreamLen ));
        if( ! ppStream )
        {
            *pBytes = 0;
            return false;
        }
        unsigned int nRead = rContext.readOrigBytes( m_pStream->m_nBeginOffset, nOuterStreamLen, *ppStream );
        if( nRead != nOuterStreamLen )
        {
            rtl_freeMemory( *ppStream );
            *ppStream = NULL;
            *pBytes = 0;
            return false;
        }
        // is there a filter entry ?
        std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
            m_pStream->m_pDict->m_aMap.find( "Filter" );
        if( it != m_pStream->m_pDict->m_aMap.end() )
        {
            PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
            if( ! pFilter )
            {
                PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
                if( pArray && ! pArray->m_aSubElements.empty() )
                {
                    pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
                }
            }
            
            // is the (first) filter FlateDecode ?
            if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
            {
                bIsDeflated = true;
            }
        }
        // prepare compressed data section
        char* pStream = *ppStream;
        if( pStream[0] == 's' )
            pStream += 6; // skip "stream"
        // skip line end after "stream"
        while( *pStream == '\r' || *pStream == '\n' )
            pStream++;
        // get the compressed length
        *pBytes = m_pStream->getDictLength( pObjectContainer );
        if( pStream != *ppStream )
            rtl_moveMemory( *ppStream, pStream, *pBytes );
        if( rContext.m_bDecrypt )
        {
            EmitImplData* pEData = getEmitData( rContext );
            pEData->decrypt( reinterpret_cast<const sal_uInt8*>(*ppStream),
                             *pBytes,
                             reinterpret_cast<sal_uInt8*>(*ppStream),
                             m_nNumber,
                             m_nGeneration
                             ); // decrypt inplace
        }
    }
    else
        *ppStream = NULL, *pBytes = 0;
    return bIsDeflated;
}

static void unzipToBuffer( const char* pBegin, unsigned int nLen,
                           sal_uInt8** pOutBuf, sal_uInt32* pOutLen )
{
    z_stream aZStr;
    aZStr.next_in       = (Bytef*)pBegin;
    aZStr.avail_in      = nLen;
	aZStr.zalloc        = ( alloc_func )0;
    aZStr.zfree         = ( free_func )0;
    aZStr.opaque        = ( voidpf )0;
    inflateInit(&aZStr);
    
    const unsigned int buf_increment_size = 16384;

    *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, buf_increment_size );
    aZStr.next_out      = (Bytef*)*pOutBuf;
    aZStr.avail_out     = buf_increment_size;
    int err = Z_OK;
    *pOutLen = buf_increment_size;
    while( err != Z_STREAM_END && err >= Z_OK && aZStr.avail_in )
    {
        err = inflate( &aZStr, Z_NO_FLUSH );
        if( aZStr.avail_out == 0 )
        {
            if( err != Z_STREAM_END )
            {
                const int nNewAlloc = *pOutLen + buf_increment_size;
                *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, nNewAlloc );
                aZStr.next_out = (Bytef*)(*pOutBuf + *pOutLen);
                aZStr.avail_out = buf_increment_size;
                *pOutLen = nNewAlloc;
            }
        }
    }
    if( err == Z_STREAM_END )
    {
        if( aZStr.avail_out > 0 )
            *pOutLen -= aZStr.avail_out;;
    }
    inflateEnd(&aZStr);
    if( err < Z_OK )
    {
        rtl_freeMemory( *pOutBuf );
        *pOutBuf = NULL;
        *pOutLen = 0;
    }
}

bool PDFObject::writeStream( EmitContext& rWriteContext, const PDFFile* pParsedFile ) const
{
    bool bSuccess = false;
    if( m_pStream )
    {
        char* pStream = NULL;
        unsigned int nBytes = 0;
        if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes && rWriteContext.m_bDeflate )
        {
            sal_uInt8* pOutBytes = NULL;
            sal_uInt32 nOutBytes = 0;
            unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
            rWriteContext.write( pOutBytes, nOutBytes );
            rtl_freeMemory( pOutBytes );
        }
        else if( pStream && nBytes )
            rWriteContext.write( pStream, nBytes );
        rtl_freeMemory( pStream );
    }
    return bSuccess;
}

bool PDFObject::emit( EmitContext& rWriteContext ) const
{
    if( ! rWriteContext.write( "\n", 1 ) )
        return false;
    
    EmitImplData* pEData = getEmitData( rWriteContext );
    if( pEData )
        pEData->insertXref( m_nNumber, m_nGeneration, rWriteContext.getCurPos() );
    
    OStringBuffer aBuf( 32 );
    aBuf.append( sal_Int32( m_nNumber ) );
    aBuf.append( ' ' );
    aBuf.append( sal_Int32( m_nGeneration ) );
    aBuf.append( " obj\n" );
    if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
        return false;
    
    if( pEData )
        pEData->setDecryptObject( m_nNumber, m_nGeneration );
    if( (rWriteContext.m_bDeflate || rWriteContext.m_bDecrypt) && pEData )
    {
        char* pStream = NULL;
        unsigned int nBytes = 0;
        bool bDeflate = getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext );
        if( pStream && nBytes )
        {
            // unzip the stream
            sal_uInt8* pOutBytes = NULL;
            sal_uInt32 nOutBytes = 0;
            if( bDeflate && rWriteContext.m_bDeflate )
                unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
            else
            {
                // nothing to deflate, but decryption has happened
                pOutBytes = (sal_uInt8*)pStream;
                nOutBytes = (sal_uInt32)nBytes;
            }
            
            if( nOutBytes )
            {
                // clone this object
                PDFObject* pClone = static_cast<PDFObject*>(clone());
                // set length in the dictionary to new stream length
                PDFNumber* pNewLen = new PDFNumber( double(nOutBytes) );
                pClone->m_pStream->m_pDict->insertValue( "Length", pNewLen );

                if( bDeflate && rWriteContext.m_bDeflate )
                {
                    // delete flatedecode filter
                    std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
                    pClone->m_pStream->m_pDict->m_aMap.find( "Filter" );
                    if( it != pClone->m_pStream->m_pDict->m_aMap.end() )
                    {
                        PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
                        if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
                            pClone->m_pStream->m_pDict->eraseValue( "Filter" );
                        else
                        {
                            PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
                            if( pArray && ! pArray->m_aSubElements.empty() )
                            {
                                pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
                                if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
                                {
                                    delete pFilter;
                                    pArray->m_aSubElements.erase( pArray->m_aSubElements.begin() );
                                }
                            }
                        }
                    }
                }

                // write sub elements except stream
                bool bRet = true;
                unsigned int nEle = pClone->m_aSubElements.size();
                for( unsigned int i = 0; i < nEle && bRet; i++ )
                {
                    if( pClone->m_aSubElements[i] != pClone->m_pStream )
                        bRet = pClone->m_aSubElements[i]->emit( rWriteContext );
                }
                delete pClone;
                // write stream
                if( bRet )
                    rWriteContext.write( "stream\n", 7 );
                if( bRet )
                    bRet = rWriteContext.write( pOutBytes, nOutBytes );
                if( bRet )
                    bRet = rWriteContext.write( "\nendstream\nendobj\n", 18 );
                rtl_freeMemory( pStream );
                if( pOutBytes != (sal_uInt8*)pStream )
                    rtl_freeMemory( pOutBytes );
                if( pEData )
                    pEData->setDecryptObject( 0, 0 );
                return bRet;
            }
            if( pOutBytes != (sal_uInt8*)pStream )
                rtl_freeMemory( pOutBytes );
        }
        rtl_freeMemory( pStream );
    }

    bool bRet = emitSubElements( rWriteContext ) &&
                rWriteContext.write( "\nendobj\n", 8 );
    if( pEData )
        pEData->setDecryptObject( 0, 0 );
    return bRet;
}

PDFEntry* PDFObject::clone() const
{
    PDFObject* pNewOb = new PDFObject( m_nNumber, m_nGeneration );
    cloneSubElements( pNewOb->m_aSubElements );
    unsigned int nEle = m_aSubElements.size();
    for( unsigned int i = 0; i < nEle; i++ )
    {
        if( m_aSubElements[i] == m_pObject )
            pNewOb->m_pObject = pNewOb->m_aSubElements[i];
        else if( m_aSubElements[i] == m_pStream && pNewOb->m_pObject )
        {
            pNewOb->m_pStream = dynamic_cast<PDFStream*>(pNewOb->m_aSubElements[i]);
            PDFDict* pNewDict = dynamic_cast<PDFDict*>(pNewOb->m_pObject);
            if( pNewDict )
                pNewOb->m_pStream->m_pDict = pNewDict;
        }
    }
    return pNewOb;
}

PDFTrailer::~PDFTrailer()
{
}

bool PDFTrailer::emit( EmitContext& rWriteContext ) const
{
    // get xref offset
    unsigned int nXRefPos = rWriteContext.getCurPos();
    // begin xref section, object 0 is always free
    if( ! rWriteContext.write( "xref\r\n"
                               "0 1\r\n"
                               "0000000000 65535 f\r\n", 31 ) )
        return false;
    // check if we are emitting a complete PDF file
    EmitImplData* pEData = getEmitData( rWriteContext );
    if( pEData )
    {
        // emit object xrefs
        const EmitImplData::XRefTable& rXRefs = pEData->m_aXRefTable;
        EmitImplData::XRefTable::const_iterator section_begin, section_end;
        section_begin = rXRefs.begin();
        while( section_begin != rXRefs.end() )
        {
            // find end of continuous object numbers
            section_end = section_begin;
            unsigned int nLast = section_begin->first;
            while( (++section_end) != rXRefs.end() &&
                   section_end->first == nLast+1 )
                nLast = section_end->first;
            // write first object number and number of following entries
            OStringBuffer aBuf( 21 );
            aBuf.append( sal_Int32( section_begin->first ) );
            aBuf.append( ' ' );
            aBuf.append( sal_Int32(nLast - section_begin->first + 1) );
            aBuf.append( "\r\n" );
            if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
                return false;
            while( section_begin != section_end )
            {
                // write 20 char entry of form
                // 0000offset 00gen n\r\n
                aBuf.setLength( 0 );
                OString aOffset( OString::valueOf( sal_Int64(section_begin->second.second ) ) );
                int nPad = 10 - aOffset.getLength();
                for( int i = 0; i < nPad; i++ )
                    aBuf.append( '0' );
                aBuf.append( aOffset );
                aBuf.append( ' ' );
                OString aGeneration( OString::valueOf( sal_Int32(section_begin->second.first ) ) );
                nPad = 5 - aGeneration.getLength();
                for( int i = 0; i < nPad; i++ )
                    aBuf.append( '0' );
                aBuf.append( aGeneration );
                aBuf.append( " n\r\n" );
                if( ! rWriteContext.write( aBuf.getStr(), 20 ) )
                    return false;
                ++section_begin;
            }
        }
    }
    if( ! rWriteContext.write( "trailer\n", 8 ) )
        return false;
    if( ! emitSubElements( rWriteContext ) )
        return false;
    if( ! rWriteContext.write( "startxref\n", 10 ) )
        return false;
    rtl::OString aOffset( rtl::OString::valueOf( sal_Int32(nXRefPos) ) );
    if( ! rWriteContext.write( aOffset.getStr(), aOffset.getLength() ) )
        return false;
    return rWriteContext.write( "\n%%EOF\n", 7 );
}

PDFEntry* PDFTrailer::clone() const
{
    PDFTrailer* pNewTr = new PDFTrailer();
    cloneSubElements( pNewTr->m_aSubElements );
    unsigned int nEle = m_aSubElements.size();
    for( unsigned int i = 0; i < nEle; i++ )
    {
        if( m_aSubElements[i] == m_pDict )
        {
            pNewTr->m_pDict = dynamic_cast<PDFDict*>(pNewTr->m_aSubElements[i]);
            break;
        }
    }
    return pNewTr;
}

#define ENCRYPTION_KEY_LEN 16
#define ENCRYPTION_BUF_LEN 32

namespace pdfparse {
struct PDFFileImplData
{
    bool        m_bIsEncrypted;
    bool        m_bStandardHandler;
    sal_uInt32  m_nAlgoVersion;
    sal_uInt32  m_nStandardRevision;
    sal_uInt32  m_nKeyLength;
    sal_uInt8   m_aOEntry[32];
    sal_uInt8   m_aUEntry[32];
    sal_uInt32  m_nPEntry;
    OString     m_aDocID;
    rtlCipher   m_aCipher;
    rtlDigest   m_aDigest;
    
    sal_uInt8   m_aDecryptionKey[ENCRYPTION_KEY_LEN+5]; // maximum handled key length
    
    PDFFileImplData() :
        m_bIsEncrypted( false ),
        m_bStandardHandler( false ),
        m_nAlgoVersion( 0 ),
        m_nStandardRevision( 0 ),
        m_nKeyLength( 0 ),
        m_nPEntry( 0 ),
        m_aCipher( NULL ),
        m_aDigest( NULL )
    {
        rtl_zeroMemory( m_aOEntry, sizeof( m_aOEntry ) );
        rtl_zeroMemory( m_aUEntry, sizeof( m_aUEntry ) );
        rtl_zeroMemory( m_aDecryptionKey, sizeof( m_aDecryptionKey ) );
    }
    
    ~PDFFileImplData()
    {
        if( m_aCipher )
            rtl_cipher_destroyARCFOUR( m_aCipher );
        if( m_aDigest )
            rtl_digest_destroyMD5( m_aDigest );
    }
};
}

PDFFile::~PDFFile()
{
    if( m_pData )
        delete m_pData;
}

bool PDFFile::isEncrypted() const
{
    return impl_getData()->m_bIsEncrypted;
}

bool PDFFile::decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
                       unsigned int nObject, unsigned int nGeneration ) const
{
    if( ! isEncrypted() )
        return false;
    
    if( ! m_pData->m_aCipher )
        m_pData->m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
    
    // modify encryption key
    sal_uInt32 i = m_pData->m_nKeyLength;
    m_pData->m_aDecryptionKey[i++] = sal_uInt8(nObject&0xff);
    m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>8)&0xff);
    m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>16)&0xff);
    m_pData->m_aDecryptionKey[i++] = sal_uInt8(nGeneration&0xff);
    m_pData->m_aDecryptionKey[i++] = sal_uInt8((nGeneration>>8)&0xff);
    
    sal_uInt8 aSum[ENCRYPTION_KEY_LEN];
    rtl_digest_updateMD5( m_pData->m_aDigest, m_pData->m_aDecryptionKey, i );
    rtl_digest_getMD5( m_pData->m_aDigest, aSum, sizeof( aSum ) );
    
    if( i > 16 )
        i = 16;

    rtlCipherError aErr = rtl_cipher_initARCFOUR( m_pData->m_aCipher,
                                                  rtl_Cipher_DirectionDecode,
                                                  aSum, i,
                                                  NULL, 0 );
    if( aErr == rtl_Cipher_E_None )
        aErr = rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
                                         pInBuffer, nLen,
                                         pOutBuffer, nLen );
    return aErr == rtl_Cipher_E_None;
}

static const sal_uInt8 nPadString[32] =
{
    0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
    0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
};

static void pad_or_truncate_to_32( const OString& rStr, sal_Char* pBuffer )
{
    int nLen = rStr.getLength();
    if( nLen > 32 )
        nLen = 32;
    const sal_Char* pStr = rStr.getStr();
    rtl_copyMemory( pBuffer, pStr, nLen );
    int i = 0;
    while( nLen < 32 )
        pBuffer[nLen++] = nPadString[i++];
}

// pass at least pData->m_nKeyLength bytes in
static sal_uInt32 password_to_key( const OString& rPwd, sal_uInt8* pOutKey, PDFFileImplData* pData, bool bComputeO )
{
    // see PDF reference 1.4 Algorithm 3.2
    // encrypt pad string
    sal_Char aPadPwd[ENCRYPTION_BUF_LEN];
    pad_or_truncate_to_32( rPwd, aPadPwd );
    rtl_digest_updateMD5( pData->m_aDigest, aPadPwd, sizeof( aPadPwd ) );
    if( ! bComputeO )
    {
        rtl_digest_updateMD5( pData->m_aDigest, pData->m_aOEntry, 32 );
        sal_uInt8 aPEntry[4];
        aPEntry[0] = static_cast<sal_uInt8>(pData->m_nPEntry & 0xff);
        aPEntry[1] = static_cast<sal_uInt8>((pData->m_nPEntry >> 8 ) & 0xff);
        aPEntry[2] = static_cast<sal_uInt8>((pData->m_nPEntry >> 16) & 0xff);
        aPEntry[3] = static_cast<sal_uInt8>((pData->m_nPEntry >> 24) & 0xff);
        rtl_digest_updateMD5( pData->m_aDigest, aPEntry, sizeof(aPEntry) );
        rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
    }
    sal_uInt8 nSum[RTL_DIGEST_LENGTH_MD5];
    rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
    if( pData->m_nStandardRevision == 3 )
    {
        for( int i = 0; i < 50; i++ )
        {
            rtl_digest_updateMD5( pData->m_aDigest, nSum, sizeof(nSum) );
            rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
        }
    }
    sal_uInt32 nLen = pData->m_nKeyLength;
    if( nLen > RTL_DIGEST_LENGTH_MD5 )
        nLen = RTL_DIGEST_LENGTH_MD5;
    rtl_copyMemory( pOutKey, nSum, nLen );
    return nLen;
}

static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
{
    // see PDF reference 1.4 Algorithm 3.6
    bool bValid = false;
    sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
    sal_uInt8 nEncryptedEntry[ENCRYPTION_BUF_LEN];
    rtl_zeroMemory( nEncryptedEntry, sizeof(nEncryptedEntry) );
    sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, pData, false );
    // save (at this time potential) decryption key for later use
    rtl_copyMemory( pData->m_aDecryptionKey, aKey, nKeyLen );
    if( pData->m_nStandardRevision == 2 )
    {
        // see PDF reference 1.4 Algorithm 3.4
        // encrypt pad string
        rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 
                                aKey, nKeyLen,
                                NULL, 0 );
        rtl_cipher_encodeARCFOUR( pData->m_aCipher, nPadString, sizeof( nPadString ),
                                  nEncryptedEntry, sizeof( nEncryptedEntry ) );
        bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 32 ) == 0); 
    }
    else if( pData->m_nStandardRevision == 3 )
    {
        // see PDF reference 1.4 Algorithm 3.5
        rtl_digest_updateMD5( pData->m_aDigest, nPadString, sizeof( nPadString ) );
        rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
        rtl_digest_getMD5( pData->m_aDigest, nEncryptedEntry, sizeof(nEncryptedEntry) );
        rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 
                                aKey, sizeof(aKey), NULL, 0 );
        rtl_cipher_encodeARCFOUR( pData->m_aCipher,
                                  nEncryptedEntry, 16,
                                  nEncryptedEntry, 16 ); // encrypt in place
        for( int i = 1; i <= 19; i++ ) // do it 19 times, start with 1
        {
            sal_uInt8 aTempKey[ENCRYPTION_KEY_LEN];
            for( sal_uInt32 j = 0; j < sizeof(aTempKey); j++ )
                aTempKey[j] = static_cast<sal_uInt8>( aKey[j] ^ i );
            
            rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 
                                    aTempKey, sizeof(aTempKey), NULL, 0 );
            rtl_cipher_encodeARCFOUR( pData->m_aCipher,
                                      nEncryptedEntry, 16,
                                      nEncryptedEntry, 16 ); // encrypt in place
        }
        bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 16 ) == 0); 
    }
    return bValid;
}

bool PDFFile::setupDecryptionData( const OString& rPwd ) const
{
    if( !impl_getData()->m_bIsEncrypted )
        return rPwd.getLength() == 0;
    
    // check if we can handle this encryption at all
    if( ! m_pData->m_bStandardHandler ||
        m_pData->m_nAlgoVersion < 1 ||
        m_pData->m_nAlgoVersion > 2 ||
        m_pData->m_nStandardRevision < 2 ||
        m_pData->m_nStandardRevision > 3 )
        return false;
    
    if( ! m_pData->m_aCipher )
        m_pData->m_aCipher = rtl_cipher_createARCFOUR(rtl_Cipher_ModeStream);
    if( ! m_pData->m_aDigest )
        m_pData->m_aDigest = rtl_digest_createMD5();
    
    // first try user password
    bool bValid = check_user_password( rPwd, m_pData );
    
    if( ! bValid )
    {
        // try owner password
        // see PDF reference 1.4 Algorithm 3.7
        sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
        sal_uInt8 nPwd[ENCRYPTION_BUF_LEN];
        rtl_zeroMemory( nPwd, sizeof(nPwd) );
        sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, m_pData, true );
        if( m_pData->m_nStandardRevision == 2 )
        {
            rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode, 
                                    aKey, nKeyLen, NULL, 0 );
            rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
                                      m_pData->m_aOEntry, 32,
                                      nPwd, 32 );
        }
        else if( m_pData->m_nStandardRevision == 3 )
        {
            rtl_copyMemory( nPwd, m_pData->m_aOEntry, 32 );
            for( int i = 19; i >= 0; i-- )
            {
                sal_uInt8 nTempKey[ENCRYPTION_KEY_LEN];
                for( unsigned int j = 0; j < sizeof(nTempKey); j++ )
                    nTempKey[j] = sal_uInt8(aKey[j] ^ i);
                rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode, 
                                        nTempKey, nKeyLen, NULL, 0 );
                rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
                                          nPwd, 32,
                                          nPwd, 32 ); // decrypt inplace
            }
        }
        bValid = check_user_password( OString( (sal_Char*)nPwd, 32 ), m_pData );
    }

    return bValid;
}

rtl::OUString PDFFile::getDecryptionKey() const
{
    rtl::OUStringBuffer aBuf( ENCRYPTION_KEY_LEN * 2 );
    if( impl_getData()->m_bIsEncrypted )
    {
        for( sal_uInt32 i = 0; i < m_pData->m_nKeyLength; i++ )
        {
            static const sal_Unicode pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
                                                     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] >> 4) & 0x0f] );
            aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] & 0x0f)] );
        }
       
    }
    return aBuf.makeStringAndClear();
}

PDFFileImplData* PDFFile::impl_getData() const
{
    if( m_pData )
        return m_pData;
    m_pData = new PDFFileImplData();
    // check for encryption dict in a trailer
    unsigned int nElements = m_aSubElements.size();
    while( nElements-- > 0 )
    {
        PDFTrailer* pTrailer = dynamic_cast<PDFTrailer*>(m_aSubElements[nElements]);
        if( pTrailer && pTrailer->m_pDict )
        {
            // search doc id
            PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID" );
            if( doc_id != pTrailer->m_pDict->m_aMap.end() )
            {
                PDFArray* pArr = dynamic_cast<PDFArray*>(doc_id->second);
                if( pArr && pArr->m_aSubElements.size() > 0 )
                {
                    PDFString* pStr = dynamic_cast<PDFString*>(pArr->m_aSubElements[0]);
                    if( pStr )
                        m_pData->m_aDocID = pStr->getFilteredString();
                    #if OSL_DEBUG_LEVEL > 1
                    fprintf( stderr, "DocId is <" );
                    for( int i = 0; i < m_pData->m_aDocID.getLength(); i++ )
                        fprintf( stderr, "%.2x", (unsigned int)sal_uInt8(m_pData->m_aDocID.getStr()[i]) );
                    fprintf( stderr, ">\n" );
                    #endif
                }
            }
            // search Encrypt entry
            PDFDict::Map::iterator enc =
                pTrailer->m_pDict->m_aMap.find( "Encrypt" );
            if( enc != pTrailer->m_pDict->m_aMap.end() )
            {
                PDFDict* pDict = dynamic_cast<PDFDict*>(enc->second);
                if( ! pDict )
                {
                    PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(enc->second);
                    if( pRef )
                    {
                        PDFObject* pObj = findObject( pRef );
                        if( pObj && pObj->m_pObject )
                            pDict = dynamic_cast<PDFDict*>(pObj->m_pObject);
                    }
                }
                if( pDict )
                {
                    PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter" );
                    PDFDict::Map::iterator version = pDict->m_aMap.find( "V" );
                    PDFDict::Map::iterator len = pDict->m_aMap.find( "Length" );
                    PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O" );
                    PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U" );
                    PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R" );
                    PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P" );
                    if( filter != pDict->m_aMap.end() )
                    {
                        m_pData->m_bIsEncrypted = true;
                        m_pData->m_nKeyLength = 5;
                        if( version != pDict->m_aMap.end() )
                        {
                            PDFNumber* pNum = dynamic_cast<PDFNumber*>(version->second);
                            if( pNum )
                                m_pData->m_nAlgoVersion = static_cast<sal_uInt32>(pNum->m_fValue);
                        }
                        if( m_pData->m_nAlgoVersion >= 3 )
                            m_pData->m_nKeyLength = 16;
                        if( len != pDict->m_aMap.end() )
                        {
                            PDFNumber* pNum = dynamic_cast<PDFNumber*>(len->second);
                            if( pNum )
                                m_pData->m_nKeyLength = static_cast<sal_uInt32>(pNum->m_fValue) / 8;
                        }
                        PDFName* pFilter = dynamic_cast<PDFName*>(filter->second);
                        if( pFilter && pFilter->getFilteredName().equalsAscii( "Standard" ) )
                            m_pData->m_bStandardHandler = true;
                        if( o_ent != pDict->m_aMap.end() )
                        {
                            PDFString* pString = dynamic_cast<PDFString*>(o_ent->second);
                            if( pString )
                            {
                                OString aEnt = pString->getFilteredString();
                                if( aEnt.getLength() == 32 )
                                    rtl_copyMemory( m_pData->m_aOEntry, aEnt.getStr(), 32 );
                                #if OSL_DEBUG_LEVEL > 1
                                else
                                {
                                    fprintf( stderr, "O entry has length %d, should be 32 <", (int)aEnt.getLength() );
                                    for( int i = 0; i < aEnt.getLength(); i++ )
                                        fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
                                    fprintf( stderr, ">\n" );
                                }
                                #endif
                            }
                        }
                        if( u_ent != pDict->m_aMap.end() )
                        {
                            PDFString* pString = dynamic_cast<PDFString*>(u_ent->second);
                            if( pString )
                            {
                                OString aEnt = pString->getFilteredString();
                                if( aEnt.getLength() == 32 )
                                    rtl_copyMemory( m_pData->m_aUEntry, aEnt.getStr(), 32 );
                                #if OSL_DEBUG_LEVEL > 1
                                else
                                {
                                    fprintf( stderr, "U entry has length %d, should be 32 <", (int)aEnt.getLength() );
                                    for( int i = 0; i < aEnt.getLength(); i++ )
                                        fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
                                    fprintf( stderr, ">\n" );
                                }
                                #endif
                            }
                        }
                        if( r_ent != pDict->m_aMap.end() )
                        {
                            PDFNumber* pNum = dynamic_cast<PDFNumber*>(r_ent->second);
                            if( pNum )
                                m_pData->m_nStandardRevision = static_cast<sal_uInt32>(pNum->m_fValue);
                        }
                        if( p_ent != pDict->m_aMap.end() )
                        {
                            PDFNumber* pNum = dynamic_cast<PDFNumber*>(p_ent->second);
                            if( pNum )
                                m_pData->m_nPEntry = static_cast<sal_uInt32>(static_cast<sal_Int32>(pNum->m_fValue));
                            #if OSL_DEBUG_LEVEL > 1
                            fprintf( stderr, "p entry is %p\n", (void*)m_pData->m_nPEntry );
                            #endif
                        }
                        #if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "Encryption dict: sec handler: %s, version = %d, revision = %d, key length = %d\n",
                                 pFilter ? OUStringToOString( pFilter->getFilteredName(), RTL_TEXTENCODING_UTF8 ).getStr() : "<unknown>",
                                 (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, (int)m_pData->m_nKeyLength );
                        #endif
                        break;
                    }
                }
            }   
        }
    }
    
    return m_pData;
}

bool PDFFile::emit( EmitContext& rWriteContext ) const
{
    setEmitData(  rWriteContext, new EmitImplData( this ) );
    
    OStringBuffer aBuf( 32 );
    aBuf.append( "%PDF-" );
    aBuf.append( sal_Int32( m_nMajor ) );
    aBuf.append( '.' );
    aBuf.append( sal_Int32( m_nMinor ) );
    aBuf.append( "\n" );
    if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
        return false;
    return emitSubElements( rWriteContext );
}

PDFEntry* PDFFile::clone() const
{
    PDFFile* pNewFl = new PDFFile();
    pNewFl->m_nMajor = m_nMajor;
    pNewFl->m_nMinor = m_nMinor;
    cloneSubElements( pNewFl->m_aSubElements );
    return pNewFl;
}

PDFPart::~PDFPart()
{
}

bool PDFPart::emit( EmitContext& rWriteContext ) const
{
    return emitSubElements( rWriteContext );
}

PDFEntry* PDFPart::clone() const
{
    PDFPart* pNewPt = new PDFPart();
    cloneSubElements( pNewPt->m_aSubElements );
    return pNewPt;
}

