void PdfInputDevice::Seek( std::streamoff off, std::ios_base::seekdir dir )
{
    if (m_bIsSeekable)
    {
        if (m_pStream)
        {
            m_pStream->seekg( off, dir );
        }

        if (m_pFile)
        {
            int whence;
            switch( dir )
            {
                default:
                case std::ios_base::beg:
                    whence = SEEK_SET;
                    break;
                case std::ios_base::end:
                    whence = SEEK_END;
                    break;
                case std::ios_base::cur:
                    whence = SEEK_CUR;
                    break;
            }
            if( fseeko( m_pFile, off, whence ) == -1)
                PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to seek to given position in the file" );
        }
    }
    else
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Tried to seek an unseekable input device." );
    }
}
PdfContentsTokenizer::PdfContentsTokenizer( PdfCanvas* pCanvas )
    : PdfTokenizer()
{
    PdfObject* pContents = pCanvas->GetContents();
    if( pContents && pContents->IsArray()  ) 
    {
        PdfArray& a = pContents->GetArray();
        for ( PdfArray::iterator it = a.begin(); it != a.end() ; ++it )
        {
            if ( !(*it).IsReference() )
            {
                PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "/Contents array contained non-references" );

            }
            
            m_lstContents.push_back( pContents->GetOwner()->GetObject( (*it).GetReference() ) );
        }
    }
    else if ( pContents && pContents->HasStream() )
    {
        m_lstContents.push_back( pContents );
    }
    else
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Page /Contents not stream or array of streams" );
    }

    if( m_lstContents.size() )
    {
        SetCurrentContentsStream( m_lstContents.front() );
        m_lstContents.pop_front();
    }
}
TVecFilters PdfFilterFactory::CreateFilterList( const PdfObject* pObject )
{
    TVecFilters filters;

    const PdfObject* pObj    = NULL;

    if( pObject->IsDictionary() && pObject->GetDictionary().HasKey( "Filter" ) )
        pObj = pObject->GetDictionary().GetKey( "Filter" );
    else if( pObject->IsArray() )
        pObj = pObject;
    else if( pObject->IsName() ) 
        pObj = pObject;


    if (!pObj)
	// Object had no /Filter key . Return a null filter list.
	return filters;

    if( pObj->IsName() ) 
        filters.push_back( PdfFilterFactory::FilterNameToType( pObj->GetName() ) );
    else if( pObj->IsArray() ) 
    {
        TCIVariantList it = pObj->GetArray().begin();

        while( it != pObj->GetArray().end() )
        {
            if ( (*it).IsName() )
			{
                filters.push_back( PdfFilterFactory::FilterNameToType( (*it).GetName() ) );
            }
            else if ( (*it).IsReference() )
            {
                PdfObject* pFilter = pObject->GetOwner()->GetObject( (*it).GetReference() );
                if( pFilter == NULL ) 
                {
                    PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Filter array contained unexpected reference" );
                }

                filters.push_back( PdfFilterFactory::FilterNameToType( pFilter->GetName() ) );
            }
            else 
            {
                PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Filter array contained unexpected non-name type" );
			}
                
            ++it;
        }
    }

    return filters;
}
Exemple #4
0
PdfObject* PdfPagesTree::GetPageNodeFromArray( int nPageNum, const PdfArray & rKidsArray, PdfObjectList & rLstParents )
{
    if( static_cast<size_t>(nPageNum) >= rKidsArray.GetSize() )
    {
        PdfError::LogMessage( eLogSeverity_Critical, "Requesting page index %i from array of size %i\n", 
                              nPageNum, rKidsArray.size() );
        return NULL;
    }

    // TODO: Fill cache immediately with all pages 
    //       in this kids array
    PdfVariant rVar = rKidsArray[nPageNum];
    while( true ) 
    {
        if( rVar.IsArray() ) 
        {
            // Fixes some broken PDFs who have trees with 1 element kids arrays
            return GetPageNodeFromArray( 0, rVar.GetArray(), rLstParents );
        }
        else if( !rVar.IsReference() )
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_NotImplemented, "Cannot handle inline pages." );
        }

        PdfObject* pgObject = GetRoot()->GetOwner()->GetObject( rVar.GetReference() );
		if(pgObject==NULL) {
			PODOFO_RAISE_ERROR_INFO( ePdfError_PageNotFound, "Invalid reference." );
		}
        //printf("Reading %s\n", pgObject->Reference().ToString().c_str());
        // make sure the object is a /Page and not a /Pages with a single kid
        if( this->IsTypePage(pgObject) ) 
        {
            return pgObject;
        }

        // it's a /Pages with a single kid, so dereference and try again...
        if (this->IsTypePages(pgObject) ) 
        {
            if( !pgObject->GetDictionary().HasKey( "Kids" ) )
                return NULL;

            rLstParents.push_back( pgObject );
            rVar = *(pgObject->GetDictionary().GetKey( "Kids" ));
        } else {
	  // Reference to unexpected object
	  PODOFO_RAISE_ERROR_INFO( ePdfError_PageNotFound, "Reference to unexpected object." );
	}
    }

    return NULL;
}
const PdfContentsGraph::KWInfo& PdfContentsGraph::findKwById(PdfContentStreamKeyword kw)
{
    if ( kw == KW_RootNode )
    {
        PODOFO_RAISE_ERROR_INFO(ePdfError_InvalidEnumValue, "Cannot get KWInfo for root node");
    }
    static const map<PdfContentStreamKeyword,const KWInfo*>::const_iterator itEnd = kwIdMap.end();
    map<PdfContentStreamKeyword,const KWInfo*>::const_iterator it = kwIdMap.find(kw);
    if ( it == itEnd)
    {
        PODOFO_RAISE_ERROR_INFO(ePdfError_InvalidEnumValue, "Bad keyword ID");
    }
    return *((*it).second);
}
void PdfFontMetricsFreetype::InitFontSizes()
{
    FT_Error ftErr;

    if( !m_pFace )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "Cannot set font size on invalid font!" );
    }
 
    float fSize = 1.0f;
    // TODO: Maybe we have to set this for charwidth!!!
    ftErr = FT_Set_Char_Size( m_pFace, static_cast<int>(fSize*64.0), 0, 72, 72 );

    // calculate the line spacing now, as it changes only with the font size
    m_dLineSpacing        = (static_cast<double>(m_pFace->height) / m_pFace->units_per_EM);
    m_dUnderlineThickness = (static_cast<double>(m_pFace->underline_thickness) / m_pFace->units_per_EM);
    m_dUnderlinePosition  = (static_cast<double>(m_pFace->underline_position)  / m_pFace->units_per_EM);
    m_dAscent  = static_cast<double>(m_pFace->ascender) / m_pFace->units_per_EM;
    m_dDescent = static_cast<double>(m_pFace->descender) / m_pFace->units_per_EM;
    // Set default values for strikeout, in case the font has no direct values
    m_dStrikeOutPosition  = m_dAscent / 2.0; 
    m_dStrikeOutThickness = m_dUnderlineThickness;

    TT_OS2* pOs2Table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table( m_pFace, ft_sfnt_os2 ));
    if( pOs2Table ) 
    {
        m_dStrikeOutPosition  = static_cast<double>(pOs2Table->yStrikeoutPosition) / m_pFace->units_per_EM;
        m_dStrikeOutThickness = static_cast<double>(pOs2Table->yStrikeoutSize) / m_pFace->units_per_EM;
    }
}
PdfOutputDevice::PdfOutputDevice( const wchar_t* pszFilename, bool bTruncate )
{
    this->Init();

    if( !pszFilename ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    m_hFile = _wfopen( pszFilename, bTruncate ? L"w+b" : L"r+b" );
    if( !m_hFile )
    {
        PdfError e( ePdfError_FileNotFound, __FILE__, __LINE__ );
        e.SetErrorInformation( pszFilename );
        throw e;
    }

    if( !bTruncate )
    {
        if( fseeko( m_hFile, 0, SEEK_END ) == -1 )
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "Failed to seek to the end of the file" );
        }

        m_ulPosition = ftello( m_hFile );
        m_ulLength = m_ulPosition;
    }
}
PdfOutputDevice::PdfOutputDevice( const char* pszFilename, bool bTruncate )
{
    this->Init();

    if( !pszFilename ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    std::ios_base::openmode openmode = std::fstream::binary | std::ios_base::in | std::ios_base::out;
    if( bTruncate )
        openmode |= std::ios_base::trunc;

    std::fstream *pStream = new std::fstream( pszFilename, openmode );
    if( pStream->fail() )
    {
        delete pStream;
        PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename );
    }

    m_pStream = pStream;
    m_pReadStream = pStream;
    PdfLocaleImbue( *m_pStream );

    if( !bTruncate )
    {
        m_pStream->seekp( 0, std::ios_base::end );

        m_ulPosition = m_pStream->tellp();
        m_ulLength = m_ulPosition;
    }
}
void PdfOutputDevice::Write( const char* pBuffer, size_t lLen )
{
    if( m_hFile )
    {
        if( fwrite( pBuffer, sizeof(char), lLen, m_hFile ) != static_cast<size_t>(lLen) )
        {
            PODOFO_RAISE_ERROR( ePdfError_UnexpectedEOF );
        }
    }
    else if( m_pBuffer )
    {
        if( m_ulPosition + lLen <= m_lBufferLen )
        {
            memcpy( m_pBuffer + m_ulPosition, pBuffer, lLen );
        }
        else
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Allocated buffer to small for PdfOutputDevice. Cannot write!"  );
        }
    }
    else if( m_pStream )
    {
        m_pStream->write( pBuffer, lLen );
    }
    else if( m_pRefCountedBuffer ) 
    {
        if( m_ulPosition + lLen > m_pRefCountedBuffer->GetSize() )
            m_pRefCountedBuffer->Resize( m_ulPosition + lLen );

        memcpy( m_pRefCountedBuffer->GetBuffer() + m_ulPosition, pBuffer, lLen );
    }

    m_ulPosition += static_cast<size_t>(lLen);
	if(m_ulPosition>m_ulLength) m_ulLength = m_ulPosition;
}
Exemple #10
0
void PdfeFontType3::initGlyphs( const PdfObject* pFont )
{
    // CharProcs and Resources objects.
    PdfObject* pCharProcs = pFont->GetIndirectKey( "CharProcs" );
    PdfObject* pResources = pFont->GetIndirectKey( "Resources" );

    // No CharProcs: exception raised.
    if( !pCharProcs || !pCharProcs->IsDictionary() ) {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Entries missing in the Type 3 font dictionary." );
    }

    // Resize space vectors.
    m_mapCIDToGID.resize( m_lastCID-m_firstCID+1, 0 );
    m_glyphs.resize( m_lastCID-m_firstCID+1, PdfeGlyphType3() );

    // Look at each character.
    PdfName cname;
    PdfObject* pGlyph;
    for( pdfe_cid c = m_firstCID ; c <= m_lastCID ; ++c ) {
        // Get character name and search it in CharProcs.
        cname = this->fromCIDToName( c );
        pGlyph = pCharProcs->GetIndirectKey( cname );

        // If found, set GID to c-m_firstCID+1 and create glyph.
        if( pGlyph ) {
            m_mapCIDToGID[c-m_firstCID] = c-m_firstCID+1;
            m_glyphs[c-m_firstCID] = PdfeGlyphType3( cname, pGlyph, pResources );
        }
    }
}
Exemple #11
0
EPdfFilter PdfFilterFactory::FilterNameToType( const PdfName & name, bool bSupportShortNames )
{
    int i = 0;

    while( aszFilters[i] )
    {
        if( name == aszFilters[i] )
            return static_cast<EPdfFilter>(i);
        
        ++i;
    }

    if( bSupportShortNames )
    {
        i = 0;
        while( aszShortFilters[i] )
        {
            if( name == aszShortFilters[i] )
                return static_cast<EPdfFilter>(i);
            
            ++i;
        }        
    }

    PODOFO_RAISE_ERROR_INFO( ePdfError_UnsupportedFilter, name.GetName().c_str() );
}
Exemple #12
0
void PdfFont::WriteStringToStream( const PdfString & rsString, PdfStream* pStream )
{
    if( !m_pEncoding )
    {
	PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    PdfString sEncoded = m_pEncoding->ConvertToEncoding( rsString, this );
    if( sEncoded.IsUnicode() ) 
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InternalLogic, "ConvertToEncoding must not return a unicode string" );
    }

    pdf_long  lLen    = 0;
    char* pBuffer = NULL;

    std::auto_ptr<PdfFilter> pFilter = PdfFilterFactory::Create( ePdfFilter_ASCIIHexDecode );    
    pFilter->Encode( sEncoded.GetString(), sEncoded.GetLength(), &pBuffer, &lLen );

    pStream->Append( "<", 1 );
    pStream->Append( pBuffer, lLen );
    pStream->Append( ">", 1 );

    free( pBuffer );
}
Exemple #13
0
void PdfAnnotation::SetQuadPoints( const PdfArray & rQuadPoints )
{
    if ( m_eAnnotation != ePdfAnnotation_Highlight )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InternalLogic, "Must be a highlight annotation to set quad points" );

    m_pObject->GetDictionary().AddKey( "QuadPoints", rQuadPoints );
}
PdfFileInputStream::PdfFileInputStream( const char* pszFilename )
{
    m_hFile = fopen( pszFilename, "rb" );
    if( !m_hFile ) 
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename );
    }
}
Exemple #15
0
void PdfParser::ReadObjectFromStream( int nObjNo, int )
{
    // check if we already have read all objects
    // from this stream
    if( m_setObjectStreams.find( nObjNo ) != m_setObjectStreams.end() )
    {
        return;
    }
    else
        m_setObjectStreams.insert( nObjNo );

    // generation number of object streams is always 0
    PdfParserObject * const pStream = dynamic_cast<PdfParserObject*>(m_vecObjects->GetObject( PdfReference( nObjNo, 0 ) ) );
    if( !pStream )
    {
        std::ostringstream oss;
        oss << "Loading of object " << nObjNo << " 0 R failed!" << std::endl;

        PODOFO_RAISE_ERROR_INFO( ePdfError_NoObject, oss.str().c_str() );
    }

    long long lNum   = pStream->GetDictionary().GetKeyAsLong( "N", 0 );
    long long lFirst = pStream->GetDictionary().GetKeyAsLong( "First", 0 );

    char * pBuffer;
    pdf_long lBufferLen;

    pStream->GetStream()->GetFilteredCopy( &pBuffer, &lBufferLen );

    // the object stream is not needed anymore in the final PDF
    delete m_vecObjects->RemoveObject( pStream->Reference() );

    PdfRefCountedInputDevice device( pBuffer, lBufferLen );
    PdfTokenizer             tokenizer( device, m_buffer );
    PdfVariant               var;
    int                      i = 0;

    while( static_cast<long long>(i) < lNum )
    {
        const long long lObj     = tokenizer.GetNextNumber();
        const long long lOff     = tokenizer.GetNextNumber();
        const std::streamoff pos = device.Device()->Tell();

        // move to the position of the object in the stream
        device.Device()->Seek( static_cast<std::streamoff>(lFirst + lOff) );

        tokenizer.GetNextVariant( var, m_pEncrypt );
        m_vecObjects->push_back( new PdfObject( PdfReference( static_cast<int>(lObj), 0LL ), var ) );

        // move back to the position inside of the table of contents
        device.Device()->Seek( pos );

        ++i;
    }

    free( pBuffer );
}
Exemple #16
0
const PdfString & PdfParser::GetDocumentId()
{
    if( !m_pTrailer->GetDictionary().HasKey( PdfName("ID") ) )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidEncryptionDict, "No document ID found in trailer.");
    }

    return m_pTrailer->GetDictionary().GetKey( PdfName("ID") )->GetArray()[0].GetString();
}
Exemple #17
0
void PdfParser::SetPassword( const std::string & sPassword )
{
    if( !m_pEncrypt )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InternalLogic, "Cannot set password for unencrypted PDF." );
    }

    bool bAuthenticate = m_pEncrypt->Authenticate( sPassword, this->GetDocumentId() );
    if( !bAuthenticate )
    {
#ifdef PODOFO_VERBOSE_DEBUG
        PdfError::DebugMessage("Authentication with user password failed\n" );
#endif // PODOFO_VERBOSE_DEBUG
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidPassword, "Authentication with user specified password failed.");
    }

    ReadObjectsInternal();
}
void PdfAnnotation::SetQuadPoints( const PdfArray & rQuadPoints )
{
    if ( m_eAnnotation != ePdfAnnotation_Highlight &&
            m_eAnnotation != ePdfAnnotation_Underline &&
            m_eAnnotation != ePdfAnnotation_Squiggly  &&
            m_eAnnotation != ePdfAnnotation_StrikeOut )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InternalLogic, "Must be a text markup annotation (hilight, underline, squiggly or strikeout) to set quad points" );

    this->GetObject()->GetDictionary().AddKey( "QuadPoints", rQuadPoints );
}
PdfPage* PdfDestination::GetPage( PdfVecObjects* pVecObjects )
{
    PdfDocument* pDoc = pVecObjects->GetParentDocument();
    if( !pDoc ) 
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle,
                                 "PdfVecObjects needs a parent PdfDocument to resolve pages." );
    }
     
    return this->GetPage( pDoc );
}
pdf_long PdfFileInputStream::GetFileLength()
{
    pdf_long lOffset = ftello( m_hFile );
    pdf_long lLen;

    if( lOffset == -1 )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to read current position in the file" );

    if( fseeko( m_hFile, 0L, SEEK_END ) == -1 )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to seek at the end of the file" );

    lLen = ftello( m_hFile );
    if( lLen == -1 )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to read file length" );

    if( fseeko( m_hFile, lOffset, SEEK_SET ) == -1 )
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to seek back to the previous position of the file" );

    return lLen;
}
int PdfInputDevice::Look() const 
{
    if (m_pStream)
        return m_pStream->peek();
    if (m_pFile) {
        pdf_long lOffset = ftello( m_pFile );

        if( lOffset == -1 )
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to read the current file position" );

        int ch = GetChar();

        if( fseeko( m_pFile, lOffset, SEEK_SET ) == -1 )
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Failed to seek back to the previous position" );

        return ch;
    }

    return 0;
}
Exemple #22
0
PdfParser::PdfParser( PdfVecObjects* pVecObjects, const PdfRefCountedInputDevice & rDevice,
                      bool bLoadOnDemand )
    : PdfTokenizer(), m_vecObjects( pVecObjects )
{
    this->Init();

    if( !rDevice.Device() )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "Cannot create PdfRefCountedInputDevice." );
    }

    this->ParseFile( rDevice, bLoadOnDemand );
}
Exemple #23
0
void PdfParser::ParseFile( const char* pszFilename, bool bLoadOnDemand )
{
    if( !pszFilename || !pszFilename[0] )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    PdfRefCountedInputDevice device( pszFilename, "rb" );
    if( !device.Device() )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename );
    }

    this->ParseFile( device, bLoadOnDemand );
}
Exemple #24
0
void PdfParser::ParseFile( const char* pBuffer, long lLen, bool bLoadOnDemand )
{
    if( !pBuffer || !lLen )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    PdfRefCountedInputDevice device( pBuffer, lLen );
    if( !device.Device() )
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "Cannot create PdfParser from buffer." );
    }

    this->ParseFile( device, bLoadOnDemand );
}
Exemple #25
0
PdfeGlyphType3::PdfeGlyphType3( const PdfName& glyphName,
                                PdfObject* glyphStream,
                                PdfObject* fontResources ) :
    PdfeCanvasAnalysis(), PdfCanvas(),
    m_name( glyphName ), m_pStream( glyphStream ), m_pResources( fontResources ),
    m_isBBoxComputed( false ), m_bboxD1( 0,0,0,0 ), m_cbox( 0,0,0,0 )
{
    // Not stream in the object...
    if( !m_pStream->HasStream() ) {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "The glyph description object does not contain a stream." );
    }

    // Compute glyph bounding box.
    this->computeBBox();
}
Exemple #26
0
PdfInputDevice::PdfInputDevice( const char* pszFilename )
{
    this->Init();

    if( !pszFilename ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    try {
        m_pFile = fopen(pszFilename, "rb");
        //m_pStream = new std::ifstream( pszFilename, std::ios::binary );
        if( !m_pFile)
        {
            PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename );
        }
        m_StreamOwned = true;
    }
    catch(...) {
        // should probably check the exact error, but for now it's a good error
        PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename );
    }
    //PdfLocaleImbue(*m_pStream);
}
void PdfLocaleImbue(std::ios_base& s)
{
#if USE_CXX_LOCALE
    static const std::locale cachedLocale( PdfIOLocale );
    try {
    	s.imbue( cachedLocale );
    } catch (const std::runtime_error & e) {
        std::ostringstream s;
        s << "Failed to set safe locale on stream being used for PDF I/O.";
        s << "Locale set was: \"" << PdfIOLocale << "\".";
        s << "Error reported by STL std::locale: \"" << e.what() << "\"";
        // The info string is copied by PdfError so we're ok to just:
        PODOFO_RAISE_ERROR_INFO(
            ePdfError_InvalidDeviceOperation,
            s.str().c_str()
            );
    }
#endif
}
Exemple #28
0
void PdfInputDevice::Seek( std::streamoff off, std::ios_base::seekdir dir )
{
    if (m_bIsSeekable)
    {
        if (m_pStream)
        {
            m_pStream->seekg( off, dir );
        }

        if (m_pFile)
        {
            fseeko( m_pFile, off, dir );
        }
    }
    else
    {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDeviceOperation, "Tried to seek an unseekable input device." );
    }
}
Exemple #29
0
void PdfParser::FindToken( const char* pszToken, const long lRange )
{
    m_device.Device()->Seek( 0, std::ios_base::end );

    std::streamoff nFileSize = m_device.Device()->Tell();
    if (nFileSize == -1)
    {
        PODOFO_RAISE_ERROR_INFO(
                ePdfError_NoXRef,
                "Failed to seek to EOF when looking for xref");
    }

    pdf_long lXRefBuf  = PDF_MIN( nFileSize, lRange );
    size_t   nTokenLen = strlen( pszToken );

    m_device.Device()->Seek( -lXRefBuf, std::ios_base::cur );
    if( m_device.Device()->Read( m_buffer.GetBuffer(), lXRefBuf ) != lXRefBuf && !m_device.Device()->Eof() )
    {
        PODOFO_RAISE_ERROR( ePdfError_NoXRef );
    }

    m_buffer.GetBuffer()[lXRefBuf] = '\0';

    int i; // Do not make this unsigned, this will cause infinte loops in files without trailer

    // search backwards in the buffer in case the buffer contains null bytes
    // because it is right after a stream (can't use strstr for this reason)
    for( i = lXRefBuf - nTokenLen; i >= 0; i-- )
    {
        if( strncmp( m_buffer.GetBuffer()+i, pszToken, nTokenLen ) == 0 )
        {
            break;
        }
    }

    if( !i )
    {
        PODOFO_RAISE_ERROR( ePdfError_InternalLogic );
    }

    m_device.Device()->Seek( (lXRefBuf-i)*-1, std::ios_base::end );
}
void PdfDestination::Init( PdfObject* pObject, PdfDocument* pDocument )
{
    bool bValueExpected = false;
    PdfObject* pValue = NULL;

    if ( pObject->GetDataType() == ePdfDataType_Array ) 
    {
        m_array = pObject->GetArray();
        m_pObject = pObject;
    }
    else if( pObject->GetDataType() == ePdfDataType_String ) 
    {
        PdfNamesTree* pNames = pDocument->GetNamesTree( ePdfDontCreateObject );
        if( !pNames ) 
        {
            PODOFO_RAISE_ERROR( ePdfError_NoObject );
        }
            
        pValue = pNames->GetValue( "Dests", pObject->GetString() );
        bValueExpected = true;
    }
    else if( pObject->GetDataType() == ePdfDataType_Name )
    {
        PdfMemDocument* pMemDoc = dynamic_cast<PdfMemDocument*>(pDocument);
        if ( !pMemDoc )
        { 
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle,
                "For reading from a document, only use PdfMemDocument." );
        }

        PdfObject* pCatalog = pMemDoc->GetCatalog();
        if ( !pCatalog )
        {
            PODOFO_RAISE_ERROR( ePdfError_NoObject );
        }
 
        PdfObject* pDests = pCatalog->GetIndirectKey( PdfName( "Dests" ) );
        if( !pDests )
        {
            // The error code has been chosen for its distinguishability.
            PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidKey,
                "No PDF-1.1-compatible destination dictionary found." );
        }
        pValue = pDests->GetIndirectKey( pObject->GetName() );
        bValueExpected = true;
    } 
    else
    {
        PdfError::LogMessage( eLogSeverity_Error, "Unsupported object given to"
            " PdfDestination::Init of type %s", pObject->GetDataTypeString() );
        m_array = PdfArray(); // needed to prevent crash on method calls
        // needed for GetObject() use w/o checking its return value for NULL
        m_pObject = pDocument->GetObjects()->CreateObject( m_array );
    }
    if ( bValueExpected )
    {
        if( !pValue ) 
        {
            PODOFO_RAISE_ERROR( ePdfError_InvalidName );
        }

        if( pValue->IsArray() ) 
            m_array = pValue->GetArray();
        else if( pValue->IsDictionary() )
            m_array = pValue->GetDictionary().GetKey( "D" )->GetArray();
        m_pObject = pValue;
    }
}