1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <pdfparse.hxx>
23 // boost using obsolete stuff
26 #pragma warning(disable:4996)
27 #pragma warning(disable:4503)
30 // workaround windows compiler: do not include multi_pass.hpp
31 #include <boost/spirit/include/classic_core.hpp>
32 #include <boost/spirit/include/classic_utility.hpp>
33 #include <boost/spirit/include/classic_error_handling.hpp>
34 #include <boost/spirit/include/classic_file_iterator.hpp>
35 #include <boost/bind.hpp>
39 #include <rtl/strbuf.hxx>
40 #include <rtl/ustrbuf.hxx>
41 #include <sal/log.hxx>
43 // disable warnings again because someone along the line has enabled them
44 // (we have included boost headers, what did you expect?)
47 #pragma warning(disable:4996)
48 #pragma warning(disable:4503)
52 using namespace boost::spirit
;
53 using namespace pdfparse
;
56 class StringEmitContext
: public EmitContext
60 StringEmitContext() : EmitContext(), m_aBuf(256) {}
62 virtual bool write( const void* pBuf
, unsigned int nLen
) throw() override
64 m_aBuf
.append( static_cast<const sal_Char
*>(pBuf
), nLen
);
67 virtual unsigned int getCurPos() throw() override
{ return m_aBuf
.getLength(); }
68 virtual bool copyOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
) throw() override
69 { return (nOrigOffset
+nLen
< static_cast<unsigned int>(m_aBuf
.getLength()) ) &&
70 write( m_aBuf
.getStr() + nOrigOffset
, nLen
); }
71 virtual unsigned int readOrigBytes( unsigned int nOrigOffset
, unsigned int nLen
, void* pBuf
) throw() override
73 if( nOrigOffset
+nLen
< static_cast<unsigned int>(m_aBuf
.getLength()) )
75 memcpy( pBuf
, m_aBuf
.getStr()+nOrigOffset
, nLen
);
81 OString
getString() { return m_aBuf
.makeStringAndClear(); }
84 template< class iteratorT
>
85 class PDFGrammar
: public grammar
< PDFGrammar
<iteratorT
> >
89 explicit PDFGrammar( const iteratorT
& first
)
90 : m_fDouble( 0.0 ), m_aGlobalBegin( first
) {}
93 if( !m_aObjectStack
.empty() )
94 delete m_aObjectStack
.front();
98 std::vector
< unsigned int > m_aUIntStack
;
99 std::vector
< PDFEntry
* > m_aObjectStack
;
100 OString m_aErrorString
;
101 iteratorT m_aGlobalBegin
;
104 struct pdf_string_parser
106 typedef nil_t result_t
;
107 template <typename ScannerT
>
109 operator()(ScannerT
const& scan
, result_t
&) const
111 std::ptrdiff_t len
= 0;
114 while( ! scan
.at_end() )
120 if( nBraceLevel
< 0 )
125 else if( c
== '\\' ) // ignore escaped braces
128 ++scan
.first
; // tdf#63054: avoid skipping spaces
129 if( scan
.first
== scan
.last
) // tdf#63054: avoid skipping spaces
135 return scan
.at_end() ? -1 : len
;
139 template< typename ScannerT
>
142 explicit definition( const PDFGrammar
<iteratorT
>& rSelf
)
144 PDFGrammar
<iteratorT
>* pSelf
= const_cast< PDFGrammar
<iteratorT
>* >( &rSelf
);
146 // workaround workshop compiler: comment_p doesn't work
147 // comment = comment_p("%")[boost::bind(&PDFGrammar::pushComment, pSelf, _1, _2 )];
148 comment
= lexeme_d
[ (ch_p('%') >> *(~ch_p('\r') & ~ch_p('\n')) >> eol_p
)[boost::bind(&PDFGrammar::pushComment
, pSelf
, _1
, _2
)] ];
150 boolean
= (str_p("true") | str_p("false"))[boost::bind(&PDFGrammar::pushBool
, pSelf
, _1
, _2
)];
152 // workaround workshop compiler: confix_p doesn't work
153 //stream = confix_p( "stream", *anychar_p, "endstream" )[boost::bind(&PDFGrammar::emitStream, pSelf, _1, _2 )];
154 stream
= (str_p("stream") >> *(anychar_p
- str_p("endstream")) >> str_p("endstream"))[boost::bind(&PDFGrammar::emitStream
, pSelf
, _1
, _2
)];
158 >> (*(anychar_p
-chset_p("\t\n\f\r ()<>[]{}/%")-ch_p('\0')))
159 [boost::bind(&PDFGrammar::pushName
, pSelf
, _1
, _2
)] ];
161 // workaround workshop compiler: confix_p doesn't work
162 //stringtype = ( confix_p("(",*anychar_p, ")") |
163 // confix_p("<",*xdigit_p, ">") )
164 // [boost::bind(&PDFGrammar::pushString,pSelf, _1, _2)];
166 stringtype
= ( ( ch_p('(') >> functor_parser
<pdf_string_parser
>() >> ch_p(')') ) |
167 ( ch_p('<') >> *xdigit_p
>> ch_p('>') ) )
168 [boost::bind(&PDFGrammar::pushString
,pSelf
, _1
, _2
)];
170 null_object
= str_p( "null" )[boost::bind(&PDFGrammar::pushNull
, pSelf
, _1
, _2
)];
172 #ifdef USE_ASSIGN_ACTOR
173 objectref
= ( uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
174 >> uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
177 )[boost::bind(&PDFGrammar::pushObjectRef
, pSelf
, _1
, _2
)];
179 objectref
= ( uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
180 >> uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
183 )[boost::bind(&PDFGrammar::pushObjectRef
, pSelf
, _1
, _2
)];
186 #ifdef USE_ASSIGN_ACTOR
187 simple_type
= objectref
| name
|
188 ( real_p
[assign_a(pSelf
->m_fDouble
)] >> eps_p
)
189 [boost::bind(&PDFGrammar::pushDouble
, pSelf
, _1
, _2
)]
190 | stringtype
| boolean
| null_object
;
192 simple_type
= objectref
| name
|
193 ( real_p
[boost::bind(&PDFGrammar::assign_action_double
, pSelf
, _1
)] >> eps_p
)
194 [boost::bind(&PDFGrammar::pushDouble
, pSelf
, _1
, _2
)]
195 | stringtype
| boolean
| null_object
;
198 dict_begin
= str_p( "<<" )[boost::bind(&PDFGrammar::beginDict
, pSelf
, _1
, _2
)];
199 dict_end
= str_p( ">>" )[boost::bind(&PDFGrammar::endDict
, pSelf
, _1
, _2
)];
201 array_begin
= str_p("[")[boost::bind(&PDFGrammar::beginArray
,pSelf
, _1
, _2
)];
202 array_end
= str_p("]")[boost::bind(&PDFGrammar::endArray
,pSelf
, _1
, _2
)];
204 #ifdef USE_ASSIGN_ACTOR
205 object_begin
= uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
206 >> uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
207 >> str_p("obj" )[boost::bind(&PDFGrammar::beginObject
, pSelf
, _1
, _2
)];
209 object_begin
= uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
210 >> uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
211 >> str_p("obj" )[boost::bind(&PDFGrammar::beginObject
, pSelf
, _1
, _2
)];
213 object_end
= str_p( "endobj" )[boost::bind(&PDFGrammar::endObject
, pSelf
, _1
, _2
)];
215 xref
= str_p( "xref" ) >> uint_p
>> uint_p
217 +( repeat_p(10)[digit_p
]
219 >> repeat_p(5)[digit_p
]
221 >> ( ch_p('n') | ch_p('f') )
222 >> repeat_p(2)[space_p
]
225 dict_element
= dict_begin
| comment
| simple_type
226 | array_begin
| array_end
| dict_end
;
228 object
= object_begin
233 trailer
= str_p( "trailer" )[boost::bind(&PDFGrammar::beginTrailer
,pSelf
,_1
,_2
)]
235 >> str_p("startxref")
237 >> str_p("%%EOF")[boost::bind(&PDFGrammar::endTrailer
,pSelf
,_1
,_2
)];
239 #ifdef USE_ASSIGN_ACTOR
240 pdfrule
= ! (lexeme_d
[
242 >> uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
244 >> uint_p
[push_back_a(pSelf
->m_aUIntStack
)]
245 >> *((~ch_p('\r') & ~ch_p('\n')))
247 ])[boost::bind(&PDFGrammar::haveFile
,pSelf
, _1
, _2
)]
248 >> *( comment
| object
| ( xref
>> trailer
) );
250 pdfrule
= ! (lexeme_d
[
252 >> uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
254 >> uint_p
[boost::bind(&PDFGrammar::push_back_action_uint
, pSelf
, _1
)]
255 >> *(~ch_p('\r') & ~ch_p('\n'))
257 ])[boost::bind(&PDFGrammar::haveFile
,pSelf
, _1
, _2
)]
258 >> *( comment
| object
| ( xref
>> trailer
) );
261 rule
< ScannerT
> comment
, stream
, boolean
, name
, stringtype
, null_object
, simple_type
,
262 objectref
, array
, value
, dict_element
, dict_begin
, dict_end
,
263 array_begin
, array_end
, object
, object_begin
, object_end
,
264 xref
, trailer
, pdfrule
;
266 const rule
< ScannerT
>& start() const { return pdfrule
; }
269 #ifndef USE_ASSIGN_ACTOR
270 void push_back_action_uint( unsigned int i
)
272 m_aUIntStack
.push_back( i
);
274 void assign_action_double( double d
)
280 static void parseError( const char* pMessage
, iteratorT pLocation
)
282 throw_( pLocation
, pMessage
);
285 OString
iteratorToString( iteratorT first
, iteratorT last
) const
287 OStringBuffer
aStr( 32 );
288 while( first
!= last
)
290 aStr
.append( *first
);
293 return aStr
.makeStringAndClear();
296 void haveFile( iteratorT pBegin
, SAL_UNUSED_PARAMETER iteratorT
/*pEnd*/ )
298 if( m_aObjectStack
.empty() )
300 PDFFile
* pFile
= new PDFFile();
301 pFile
->m_nMinor
= m_aUIntStack
.back();
302 m_aUIntStack
.pop_back();
303 pFile
->m_nMajor
= m_aUIntStack
.back();
304 m_aUIntStack
.pop_back();
305 m_aObjectStack
.push_back( pFile
);
308 parseError( "found file header in unusual place", pBegin
);
311 void pushComment( iteratorT first
, iteratorT last
)
313 // add a comment to the current stack element
314 PDFComment
* pComment
=
315 new PDFComment(iteratorToString(first
,last
));
316 if( m_aObjectStack
.empty() )
317 m_aObjectStack
.push_back( new PDFPart() );
318 PDFContainer
* pContainer
= dynamic_cast<PDFContainer
*>(m_aObjectStack
.back());
319 if( pContainer
== nullptr )
320 parseError( "comment without container", first
);
321 pContainer
->m_aSubElements
.emplace_back( pComment
);
324 void insertNewValue( std::unique_ptr
<PDFEntry
> pNewValue
, iteratorT pPos
)
326 PDFContainer
* pContainer
= nullptr;
327 const char* pMsg
= nullptr;
328 if( ! m_aObjectStack
.empty() &&
329 (pContainer
= dynamic_cast<PDFContainer
*>(m_aObjectStack
.back())) != nullptr )
331 if( dynamic_cast<PDFDict
*>(pContainer
) == nullptr &&
332 dynamic_cast<PDFArray
*>(pContainer
) == nullptr )
334 PDFObject
* pObj
= dynamic_cast<PDFObject
*>(pContainer
);
337 if( pObj
->m_pObject
== nullptr )
338 pObj
->m_pObject
= pNewValue
.get();
341 pMsg
= "second value for object";
342 pContainer
= nullptr;
345 else if( dynamic_cast<PDFDict
*>(pNewValue
.get()) )
347 PDFTrailer
* pTrailer
= dynamic_cast<PDFTrailer
*>(pContainer
);
350 if( pTrailer
->m_pDict
== nullptr )
351 pTrailer
->m_pDict
= dynamic_cast<PDFDict
*>(pNewValue
.get());
353 pContainer
= nullptr;
356 pContainer
= nullptr;
359 pContainer
= nullptr;
363 pContainer
->m_aSubElements
.emplace_back( std::move(pNewValue
) );
368 if( dynamic_cast<PDFContainer
*>(pNewValue
.get()) )
369 pMsg
= "array without container";
371 pMsg
= "value without container";
373 parseError( pMsg
, pPos
);
377 void pushName( iteratorT first
, iteratorT last
)
379 insertNewValue( std::make_unique
<PDFName
>(iteratorToString(first
,last
)), first
);
382 void pushDouble( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
/*last*/ )
384 insertNewValue( std::make_unique
<PDFNumber
>(m_fDouble
), first
);
387 void pushString( iteratorT first
, iteratorT last
)
389 insertNewValue( std::make_unique
<PDFString
>(iteratorToString(first
,last
)), first
);
392 void pushBool( iteratorT first
, iteratorT last
)
394 insertNewValue( std::make_unique
<PDFBool
>( last
-first
== 4 ), first
);
397 void pushNull( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
399 insertNewValue( std::make_unique
<PDFNull
>(), first
);
403 void beginObject( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
/*last*/ )
405 if( m_aObjectStack
.empty() )
406 m_aObjectStack
.push_back( new PDFPart() );
408 unsigned int nGeneration
= m_aUIntStack
.back();
409 m_aUIntStack
.pop_back();
410 unsigned int nObject
= m_aUIntStack
.back();
411 m_aUIntStack
.pop_back();
413 PDFObject
* pObj
= new PDFObject( nObject
, nGeneration
);
414 pObj
->m_nOffset
= first
- m_aGlobalBegin
;
416 PDFContainer
* pContainer
= dynamic_cast<PDFContainer
*>(m_aObjectStack
.back());
418 ( dynamic_cast<PDFFile
*>(pContainer
) ||
419 dynamic_cast<PDFPart
*>(pContainer
) ) )
421 pContainer
->m_aSubElements
.emplace_back( pObj
);
422 m_aObjectStack
.push_back( pObj
);
425 parseError( "object in wrong place", first
);
428 void endObject( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
430 if( m_aObjectStack
.empty() )
431 parseError( "endobj without obj", first
);
432 else if( dynamic_cast<PDFObject
*>(m_aObjectStack
.back()) == nullptr )
433 parseError( "spurious endobj", first
);
435 m_aObjectStack
.pop_back();
438 void pushObjectRef( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
440 unsigned int nGeneration
= m_aUIntStack
.back();
441 m_aUIntStack
.pop_back();
442 unsigned int nObject
= m_aUIntStack
.back();
443 m_aUIntStack
.pop_back();
444 insertNewValue( std::make_unique
<PDFObjectRef
>(nObject
,nGeneration
), first
);
447 void beginDict( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
449 PDFDict
* pDict
= new PDFDict();
450 pDict
->m_nOffset
= first
- m_aGlobalBegin
;
452 insertNewValue( std::unique_ptr
<PDFEntry
>(pDict
), first
);
453 // will not come here if insertion fails (exception)
454 m_aObjectStack
.push_back( pDict
);
456 void endDict( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
458 PDFDict
* pDict
= nullptr;
459 if( m_aObjectStack
.empty() )
460 parseError( "dictionary end without begin", first
);
461 else if( (pDict
= dynamic_cast<PDFDict
*>(m_aObjectStack
.back())) == nullptr )
462 parseError( "spurious dictionary end", first
);
464 m_aObjectStack
.pop_back();
466 PDFEntry
* pOffender
= pDict
->buildMap();
469 StringEmitContext aCtx
;
470 aCtx
.write( "offending dictionary element: ", 30 );
471 pOffender
->emit( aCtx
);
472 m_aErrorString
= aCtx
.getString();
473 parseError( m_aErrorString
.getStr(), first
);
477 void beginArray( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
479 PDFArray
* pArray
= new PDFArray();
480 pArray
->m_nOffset
= first
- m_aGlobalBegin
;
482 insertNewValue( std::unique_ptr
<PDFEntry
>(pArray
), first
);
483 // will not come here if insertion fails (exception)
484 m_aObjectStack
.push_back( pArray
);
487 void endArray( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
489 if( m_aObjectStack
.empty() )
490 parseError( "array end without begin", first
);
491 else if( dynamic_cast<PDFArray
*>(m_aObjectStack
.back()) == nullptr )
492 parseError( "spurious array end", first
);
494 m_aObjectStack
.pop_back();
497 void emitStream( iteratorT first
, iteratorT last
)
499 if( m_aObjectStack
.empty() )
500 parseError( "stream without object", first
);
501 PDFObject
* pObj
= dynamic_cast<PDFObject
*>(m_aObjectStack
.back());
502 if( pObj
&& pObj
->m_pObject
)
504 if( pObj
->m_pStream
)
505 parseError( "multiple streams in object", first
);
507 PDFDict
* pDict
= dynamic_cast<PDFDict
*>(pObj
->m_pObject
);
510 PDFStream
* pStream
= new PDFStream( first
- m_aGlobalBegin
, last
- m_aGlobalBegin
, pDict
);
512 pObj
->m_pStream
= pStream
;
513 pObj
->m_aSubElements
.emplace_back( pStream
);
517 parseError( "stream without object", first
);
520 void beginTrailer( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
522 if( m_aObjectStack
.empty() )
523 m_aObjectStack
.push_back( new PDFPart() );
525 PDFTrailer
* pTrailer
= new PDFTrailer();
526 pTrailer
->m_nOffset
= first
- m_aGlobalBegin
;
528 PDFContainer
* pContainer
= dynamic_cast<PDFContainer
*>(m_aObjectStack
.back());
530 ( dynamic_cast<PDFFile
*>(pContainer
) ||
531 dynamic_cast<PDFPart
*>(pContainer
) ) )
533 pContainer
->m_aSubElements
.emplace_back( pTrailer
);
534 m_aObjectStack
.push_back( pTrailer
);
537 parseError( "trailer in wrong place", first
);
540 void endTrailer( iteratorT first
, SAL_UNUSED_PARAMETER iteratorT
)
542 if( m_aObjectStack
.empty() )
543 parseError( "%%EOF without trailer", first
);
544 else if( dynamic_cast<PDFTrailer
*>(m_aObjectStack
.back()) == nullptr )
545 parseError( "spurious %%EOF", first
);
547 m_aObjectStack
.pop_back();
552 std::unique_ptr
<PDFEntry
> PDFReader::read( const char* pBuffer
, unsigned int nLen
)
554 PDFGrammar
<const char*> aGrammar( pBuffer
);
558 #if OSL_DEBUG_LEVEL > 0
559 boost::spirit::parse_info
<const char*> aInfo
=
561 boost::spirit::parse( pBuffer
,
564 boost::spirit::space_p
);
565 #if OSL_DEBUG_LEVEL > 0
566 SAL_INFO("sdext.pdfimport.pdfparse", "parseinfo: stop = " << aInfo
.stop
<< " (buff=" << pBuffer
<< ", offset = " << aInfo
.stop
- pBuffer
<< "), hit = " << (aInfo
.hit
? OUString("true") : OUString("false")) << ", full = " << (aInfo
.full
? OUString("true") : OUString("false")) << ", length = " << static_cast<int>(aInfo
.length
) );
569 catch( const parser_error
<const char*, const char*>& rError
)
571 #if OSL_DEBUG_LEVEL > 0
573 unsigned int nElem
= aGrammar
.m_aObjectStack
.size();
574 for( unsigned int i
= 0; i
< nElem
; i
++ )
575 aTmp
+= OStringLiteral(" ") + typeid( *(aGrammar
.m_aObjectStack
[i
]) ).name();
577 SAL_WARN("sdext.pdfimport.pdfparse", "parse error: " << rError
.descriptor
<< " at buffer pos " << rError
.where
- pBuffer
<< ", object stack: " << aTmp
);
583 std::unique_ptr
<PDFEntry
> pRet
;
584 unsigned int nEntries
= aGrammar
.m_aObjectStack
.size();
587 pRet
.reset(aGrammar
.m_aObjectStack
.back());
588 aGrammar
.m_aObjectStack
.pop_back();
590 #if OSL_DEBUG_LEVEL > 0
591 else if( nEntries
> 1 )
592 SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries
<< " stack objects in parse" );
599 std::unique_ptr
<PDFEntry
> PDFReader::read( const char* pFileName
)
603 since converting to boost 1.39 file_iterator does not work anymore on all Windows systems
604 C++ stdlib istream_iterator does not allow "-" apparently
605 using spirit 2.0 doesn't work in our environment with the MSC
607 So for the time being bite the bullet and read the whole file.
608 FIXME: give Spirit 2.x another try when we upgrade boost again.
610 std::unique_ptr
<PDFEntry
> pRet
;
611 FILE* fp
= fopen( pFileName
, "rb" );
614 fseek( fp
, 0, SEEK_END
);
615 unsigned int nLen
= static_cast<unsigned int>(ftell( fp
));
616 fseek( fp
, 0, SEEK_SET
);
617 char* pBuf
= static_cast<char*>(std::malloc( nLen
));
620 fread( pBuf
, 1, nLen
, fp
);
621 pRet
= read( pBuf
, nLen
);
628 file_iterator
<> file_start( pFileName
);
631 file_iterator
<> file_end
= file_start
.make_end();
632 PDFGrammar
< file_iterator
<> > aGrammar( file_start
);
636 #if OSL_DEBUG_LEVEL > 0
637 boost::spirit::parse_info
< file_iterator
<> > aInfo
=
639 boost::spirit::parse( file_start
,
642 boost::spirit::space_p
);
643 #if OSL_DEBUG_LEVEL > 0
644 SAL_INFO("sdext.pdfimport.pdfparse", "parseinfo: stop at offset = " << aInfo
.stop
- file_start
<< ", hit = " << (aInfo
.hit
? "true" : "false") << ", full = " << (aInfo
.full
? "true" : "false") << ", length = " << aInfo
.length
);
647 catch( const parser_error
< const char*, file_iterator
<> >& rError
)
649 SAL_WARN("sdext.pdfimport.pdfparse", "parse error: " << rError
.descriptor
<< " at buffer pos " << rError
.where
- file_start
);
650 #if OSL_DEBUG_LEVEL > 0
652 unsigned int nElem
= aGrammar
.m_aObjectStack
.size();
653 for( unsigned int i
= 0; i
< nElem
; i
++ )
656 aTmp
.appendAscii(typeid( *(aGrammar
.m_aObjectStack
[i
]) ).name());
658 SAL_WARN("sdext.pdfimport.pdfparse", "parse error object stack: " << aTmp
.makeStringAndClear());
662 std::unique_ptr
<PDFEntry
> pRet
;
663 unsigned int nEntries
= aGrammar
.m_aObjectStack
.size();
666 pRet
.reset(aGrammar
.m_aObjectStack
.back());
667 aGrammar
.m_aObjectStack
.pop_back();
669 #if OSL_DEBUG_LEVEL > 0
670 else if( nEntries
> 1 )
672 SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries
<< " stack objects in parse");
673 for( unsigned int i
= 0; i
< nEntries
; i
++ )
675 SAL_WARN("sdext.pdfimport.pdfparse", typeid(*aGrammar
.m_aObjectStack
[i
]).name());
676 PDFObject
* pObj
= dynamic_cast<PDFObject
*>(aGrammar
.m_aObjectStack
[i
]);
678 SAL_WARN("sdext.pdfimport.pdfparse", " -> object " << pObj
->m_nNumber
<< " generation " << pObj
->m_nGeneration
);
680 SAL_WARN("sdext.pdfimport.pdfparse", "(type " << typeid(*aGrammar
.m_aObjectStack
[i
]).name() << ")");
688 #if defined(_MSC_VER)
692 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */