fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sdext / source / pdfimport / pdfparse / pdfparse.cxx
blob7600d3c6a6d98fae1a57fe408166f8004d480065
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #if defined _MSC_VER
22 #pragma warning(push, 1)
23 #endif
25 #include "pdfparse.hxx"
27 // workaround windows compiler: do not include multi_pass.hpp
28 #include <boost/spirit/include/classic_core.hpp>
29 #include <boost/spirit/include/classic_utility.hpp>
30 #include <boost/spirit/include/classic_error_handling.hpp>
31 #include <boost/spirit/include/classic_file_iterator.hpp>
32 #include <boost/bind.hpp>
33 #include <string.h>
35 #include <rtl/strbuf.hxx>
36 #include <rtl/alloc.h>
38 // disable warnings again because someone along the line has enabled them
39 #if defined _MSC_VER
40 #pragma warning(push, 1)
41 #endif
43 using namespace boost::spirit;
44 using namespace pdfparse;
47 class StringEmitContext : public EmitContext
49 OStringBuffer m_aBuf;
50 public:
51 StringEmitContext() : EmitContext(), m_aBuf(256) {}
52 virtual ~StringEmitContext() {}
53 virtual bool write( const void* pBuf, unsigned int nLen ) throw() SAL_OVERRIDE
55 m_aBuf.append( static_cast<const sal_Char*>(pBuf), nLen );
56 return true;
58 virtual unsigned int getCurPos() throw() SAL_OVERRIDE { return m_aBuf.getLength(); }
59 virtual bool copyOrigBytes( unsigned int nOrigOffset, unsigned int nLen ) throw() SAL_OVERRIDE
60 { return (nOrigOffset+nLen < static_cast<unsigned int>(m_aBuf.getLength()) ) &&
61 write( m_aBuf.getStr() + nOrigOffset, nLen ); }
62 virtual unsigned int readOrigBytes( unsigned int nOrigOffset, unsigned int nLen, void* pBuf ) throw() SAL_OVERRIDE
64 if( nOrigOffset+nLen < static_cast<unsigned int>(m_aBuf.getLength()) )
66 memcpy( pBuf, m_aBuf.getStr()+nOrigOffset, nLen );
67 return nLen;
69 return 0;
72 OString getString() { return m_aBuf.makeStringAndClear(); }
75 template< class iteratorT >
76 class PDFGrammar : public grammar< PDFGrammar<iteratorT> >
78 public:
80 PDFGrammar( const iteratorT& first )
81 : m_fDouble( 0.0 ), m_aGlobalBegin( first ) {}
82 ~PDFGrammar()
84 if( !m_aObjectStack.empty() )
85 delete m_aObjectStack.front();
88 double m_fDouble;
89 std::vector< unsigned int > m_aUIntStack;
90 std::vector< PDFEntry* > m_aObjectStack;
91 OString m_aErrorString;
92 iteratorT m_aGlobalBegin;
94 public:
95 struct pdf_string_parser
97 typedef nil_t result_t;
98 template <typename ScannerT>
99 std::ptrdiff_t
100 operator()(ScannerT const& scan, result_t&) const
102 std::ptrdiff_t len = 0;
104 int nBraceLevel = 0;
105 while( ! scan.at_end() )
107 char c = *scan;
108 if( c == ')' )
110 nBraceLevel--;
111 if( nBraceLevel < 0 )
112 break;
114 else if( c == '(' )
115 nBraceLevel++;
116 else if( c == '\\' ) // ignore escaped braces
118 ++len;
119 ++scan.first; // tdf#63054: avoid skipping spaces
120 if( scan.first == scan.last ) // tdf#63054: avoid skipping spaces
121 break;
123 ++len;
124 ++scan;
126 return scan.at_end() ? -1 : len;
130 template< typename ScannerT >
131 struct definition
133 definition( const PDFGrammar<iteratorT>& rSelf )
135 PDFGrammar<iteratorT>* pSelf = const_cast< PDFGrammar<iteratorT>* >( &rSelf );
137 // workaround workshop compiler: comment_p doesn't work
138 // comment = comment_p("%")[boost::bind(&PDFGrammar::pushComment, pSelf, _1, _2 )];
139 comment = lexeme_d[ (ch_p('%') >> *(~ch_p('\r') & ~ch_p('\n')) >> eol_p)[boost::bind(&PDFGrammar::pushComment, pSelf, _1, _2 )] ];
141 boolean = (str_p("true") | str_p("false"))[boost::bind(&PDFGrammar::pushBool, pSelf, _1, _2)];
143 // workaround workshop compiler: confix_p doesn't work
144 //stream = confix_p( "stream", *anychar_p, "endstream" )[boost::bind(&PDFGrammar::emitStream, pSelf, _1, _2 )];
145 stream = (str_p("stream") >> *(anychar_p - str_p("endstream")) >> str_p("endstream"))[boost::bind(&PDFGrammar::emitStream, pSelf, _1, _2 )];
147 name = lexeme_d[
148 ch_p('/')
149 >> (*(anychar_p-chset_p("\t\n\f\r ()<>[]{}/%")-ch_p('\0')))
150 [boost::bind(&PDFGrammar::pushName, pSelf, _1, _2)] ];
152 // workaround workshop compiler: confix_p doesn't work
153 //stringtype = ( confix_p("(",*anychar_p, ")") |
154 // confix_p("<",*xdigit_p, ">") )
155 // [boost::bind(&PDFGrammar::pushString,pSelf, _1, _2)];
157 stringtype = ( ( ch_p('(') >> functor_parser<pdf_string_parser>() >> ch_p(')') ) |
158 ( ch_p('<') >> *xdigit_p >> ch_p('>') ) )
159 [boost::bind(&PDFGrammar::pushString,pSelf, _1, _2)];
161 null_object = str_p( "null" )[boost::bind(&PDFGrammar::pushNull, pSelf, _1, _2)];
163 #ifdef USE_ASSIGN_ACTOR
164 objectref = ( uint_p[push_back_a(pSelf->m_aUIntStack)]
165 >> uint_p[push_back_a(pSelf->m_aUIntStack)]
166 >> ch_p('R')
167 >> eps_p
168 )[boost::bind(&PDFGrammar::pushObjectRef, pSelf, _1, _2)];
169 #else
170 objectref = ( uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
171 >> uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
172 >> ch_p('R')
173 >> eps_p
174 )[boost::bind(&PDFGrammar::pushObjectRef, pSelf, _1, _2)];
175 #endif
177 #ifdef USE_ASSIGN_ACTOR
178 simple_type = objectref | name |
179 ( real_p[assign_a(pSelf->m_fDouble)] >> eps_p )
180 [boost::bind(&PDFGrammar::pushDouble, pSelf, _1, _2)]
181 | stringtype | boolean | null_object;
182 #else
183 simple_type = objectref | name |
184 ( real_p[boost::bind(&PDFGrammar::assign_action_double, pSelf, _1)] >> eps_p )
185 [boost::bind(&PDFGrammar::pushDouble, pSelf, _1, _2)]
186 | stringtype | boolean | null_object;
187 #endif
189 dict_begin = str_p( "<<" )[boost::bind(&PDFGrammar::beginDict, pSelf, _1, _2)];
190 dict_end = str_p( ">>" )[boost::bind(&PDFGrammar::endDict, pSelf, _1, _2)];
192 array_begin = str_p("[")[boost::bind(&PDFGrammar::beginArray,pSelf, _1, _2)];
193 array_end = str_p("]")[boost::bind(&PDFGrammar::endArray,pSelf, _1, _2)];
195 #ifdef USE_ASSIGN_ACTOR
196 object_begin= uint_p[push_back_a(pSelf->m_aUIntStack)]
197 >> uint_p[push_back_a(pSelf->m_aUIntStack)]
198 >> str_p("obj" )[boost::bind(&PDFGrammar::beginObject, pSelf, _1, _2)];
199 #else
200 object_begin= uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
201 >> uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
202 >> str_p("obj" )[boost::bind(&PDFGrammar::beginObject, pSelf, _1, _2)];
203 #endif
204 object_end = str_p( "endobj" )[boost::bind(&PDFGrammar::endObject, pSelf, _1, _2)];
206 xref = str_p( "xref" ) >> uint_p >> uint_p
207 >> lexeme_d[
208 +( repeat_p(10)[digit_p]
209 >> blank_p
210 >> repeat_p(5)[digit_p]
211 >> blank_p
212 >> ( ch_p('n') | ch_p('f') )
213 >> repeat_p(2)[space_p]
214 ) ];
216 dict_element= dict_begin | comment | simple_type
217 | array_begin | array_end | dict_end;
219 object = object_begin
220 >> *dict_element
221 >> !stream
222 >> object_end;
224 trailer = str_p( "trailer" )[boost::bind(&PDFGrammar::beginTrailer,pSelf,_1,_2)]
225 >> *dict_element
226 >> str_p("startxref")
227 >> uint_p
228 >> str_p("%%EOF")[boost::bind(&PDFGrammar::endTrailer,pSelf,_1,_2)];
230 #ifdef USE_ASSIGN_ACTOR
231 pdfrule = ! (lexeme_d[
232 str_p( "%PDF-" )
233 >> uint_p[push_back_a(pSelf->m_aUIntStack)]
234 >> ch_p('.')
235 >> uint_p[push_back_a(pSelf->m_aUIntStack)]
236 >> *((~ch_p('\r') & ~ch_p('\n')))
237 >> eol_p
238 ])[boost::bind(&PDFGrammar::haveFile,pSelf, _1, _2)]
239 >> *( comment | object | ( xref >> trailer ) );
240 #else
241 pdfrule = ! (lexeme_d[
242 str_p( "%PDF-" )
243 >> uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
244 >> ch_p('.')
245 >> uint_p[boost::bind(&PDFGrammar::push_back_action_uint, pSelf, _1)]
246 >> *((~ch_p('\r') & ~ch_p('\n')))
247 >> eol_p
248 ])[boost::bind(&PDFGrammar::haveFile,pSelf, _1, _2)]
249 >> *( comment | object | ( xref >> trailer ) );
250 #endif
252 rule< ScannerT > comment, stream, boolean, name, stringtype, null_object, simple_type,
253 objectref, array, value, dict_element, dict_begin, dict_end,
254 array_begin, array_end, object, object_begin, object_end,
255 xref, trailer, pdfrule;
257 const rule< ScannerT >& start() const { return pdfrule; }
260 #ifndef USE_ASSIGN_ACTOR
261 void push_back_action_uint( unsigned int i )
263 m_aUIntStack.push_back( i );
265 void assign_action_double( double d )
267 m_fDouble = d;
269 #endif
271 static void parseError( const char* pMessage, iteratorT pLocation )
273 throw_( pLocation, pMessage );
276 OString iteratorToString( iteratorT first, iteratorT last ) const
278 OStringBuffer aStr( 32 );
279 while( first != last )
281 aStr.append( *first );
282 ++first;
284 return aStr.makeStringAndClear();
287 void haveFile( iteratorT pBegin, SAL_UNUSED_PARAMETER iteratorT /*pEnd*/ )
289 if( m_aObjectStack.empty() )
291 PDFFile* pFile = new PDFFile();
292 pFile->m_nMinor = m_aUIntStack.back();
293 m_aUIntStack.pop_back();
294 pFile->m_nMajor = m_aUIntStack.back();
295 m_aUIntStack.pop_back();
296 m_aObjectStack.push_back( pFile );
298 else
299 parseError( "found file header in unusual place", pBegin );
302 void pushComment( iteratorT first, iteratorT last )
304 // add a comment to the current stack element
305 PDFComment* pComment =
306 new PDFComment(iteratorToString(first,last));
307 if( m_aObjectStack.empty() )
308 m_aObjectStack.push_back( new PDFPart() );
309 PDFContainer* pContainer = dynamic_cast<PDFContainer*>(m_aObjectStack.back());
310 if( pContainer == NULL )
311 parseError( "comment without container", first );
312 pContainer->m_aSubElements.push_back( pComment );
315 void insertNewValue( PDFEntry* pNewValue, iteratorT pPos )
317 PDFContainer* pContainer = NULL;
318 const char* pMsg = NULL;
319 if( ! m_aObjectStack.empty() &&
320 (pContainer = dynamic_cast<PDFContainer*>(m_aObjectStack.back())) != NULL )
322 if( dynamic_cast<PDFDict*>(pContainer) == NULL &&
323 dynamic_cast<PDFArray*>(pContainer) == NULL )
325 PDFObject* pObj = dynamic_cast<PDFObject*>(pContainer);
326 if( pObj )
328 if( pObj->m_pObject == NULL )
329 pObj->m_pObject = pNewValue;
330 else
332 pMsg = "second value for object";
333 pContainer = NULL;
336 else if( dynamic_cast<PDFDict*>(pNewValue) )
338 PDFTrailer* pTrailer = dynamic_cast<PDFTrailer*>(pContainer);
339 if( pTrailer )
341 if( pTrailer->m_pDict == NULL )
342 pTrailer->m_pDict = dynamic_cast<PDFDict*>(pNewValue);
343 else
344 pContainer = NULL;
346 else
347 pContainer = NULL;
349 else
350 pContainer = NULL;
353 if( pContainer )
354 pContainer->m_aSubElements.push_back( pNewValue );
355 else
357 if( ! pMsg )
359 if( dynamic_cast<PDFContainer*>(pNewValue) )
360 pMsg = "array without container";
361 else
362 pMsg = "value without container";
364 delete pNewValue;
365 parseError( pMsg, pPos );
369 void pushName( iteratorT first, iteratorT last )
371 insertNewValue( new PDFName(iteratorToString(first,last)), first );
374 void pushDouble( iteratorT first, SAL_UNUSED_PARAMETER iteratorT /*last*/ )
376 insertNewValue( new PDFNumber(m_fDouble), first );
379 void pushString( iteratorT first, iteratorT last )
381 insertNewValue( new PDFString(iteratorToString(first,last)), first );
384 void pushBool( iteratorT first, iteratorT last )
386 insertNewValue( new PDFBool( (last-first == 4) ), first );
389 void pushNull( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
391 insertNewValue( new PDFNull(), first );
395 void beginObject( iteratorT first, SAL_UNUSED_PARAMETER iteratorT /*last*/ )
397 if( m_aObjectStack.empty() )
398 m_aObjectStack.push_back( new PDFPart() );
400 unsigned int nGeneration = m_aUIntStack.back();
401 m_aUIntStack.pop_back();
402 unsigned int nObject = m_aUIntStack.back();
403 m_aUIntStack.pop_back();
405 PDFObject* pObj = new PDFObject( nObject, nGeneration );
406 pObj->m_nOffset = first - m_aGlobalBegin;
408 PDFContainer* pContainer = dynamic_cast<PDFContainer*>(m_aObjectStack.back());
409 if( pContainer &&
410 ( dynamic_cast<PDFFile*>(pContainer) ||
411 dynamic_cast<PDFPart*>(pContainer) ) )
413 pContainer->m_aSubElements.push_back( pObj );
414 m_aObjectStack.push_back( pObj );
416 else
417 parseError( "object in wrong place", first );
420 void endObject( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
422 if( m_aObjectStack.empty() )
423 parseError( "endobj without obj", first );
424 else if( dynamic_cast<PDFObject*>(m_aObjectStack.back()) == NULL )
425 parseError( "spurious endobj", first );
426 else
427 m_aObjectStack.pop_back();
430 void pushObjectRef( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
432 unsigned int nGeneration = m_aUIntStack.back();
433 m_aUIntStack.pop_back();
434 unsigned int nObject = m_aUIntStack.back();
435 m_aUIntStack.pop_back();
436 insertNewValue( new PDFObjectRef(nObject,nGeneration), first );
439 void beginDict( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
441 PDFDict* pDict = new PDFDict();
442 pDict->m_nOffset = first - m_aGlobalBegin;
444 insertNewValue( pDict, first );
445 // will not come here if insertion fails (exception)
446 m_aObjectStack.push_back( pDict );
448 void endDict( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
450 PDFDict* pDict = NULL;
451 if( m_aObjectStack.empty() )
452 parseError( "dictionary end without begin", first );
453 else if( (pDict = dynamic_cast<PDFDict*>(m_aObjectStack.back())) == NULL )
454 parseError( "spurious dictionary end", first );
455 else
456 m_aObjectStack.pop_back();
458 PDFEntry* pOffender = pDict->buildMap();
459 if( pOffender )
461 StringEmitContext aCtx;
462 aCtx.write( "offending dictionary element: ", 30 );
463 pOffender->emit( aCtx );
464 m_aErrorString = aCtx.getString();
465 parseError( m_aErrorString.getStr(), first );
469 void beginArray( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
471 PDFArray* pArray = new PDFArray();
472 pArray->m_nOffset = first - m_aGlobalBegin;
474 insertNewValue( pArray, first );
475 // will not come here if insertion fails (exception)
476 m_aObjectStack.push_back( pArray );
479 void endArray( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
481 if( m_aObjectStack.empty() )
482 parseError( "array end without begin", first );
483 else if( dynamic_cast<PDFArray*>(m_aObjectStack.back()) == NULL )
484 parseError( "spurious array end", first );
485 else
486 m_aObjectStack.pop_back();
489 void emitStream( iteratorT first, iteratorT last )
491 if( m_aObjectStack.empty() )
492 parseError( "stream without object", first );
493 PDFObject* pObj = dynamic_cast<PDFObject*>(m_aObjectStack.back());
494 if( pObj && pObj->m_pObject )
496 if( pObj->m_pStream )
497 parseError( "multiple streams in object", first );
499 PDFDict* pDict = dynamic_cast<PDFDict*>(pObj->m_pObject);
500 if( pDict )
502 PDFStream* pStream = new PDFStream( first - m_aGlobalBegin, last - m_aGlobalBegin, pDict );
504 pObj->m_pStream = pStream;
505 pObj->m_aSubElements.push_back( pStream );
508 else
509 parseError( "stream without object", first );
512 void beginTrailer( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
514 if( m_aObjectStack.empty() )
515 m_aObjectStack.push_back( new PDFPart() );
517 PDFTrailer* pTrailer = new PDFTrailer();
518 pTrailer->m_nOffset = first - m_aGlobalBegin;
520 PDFContainer* pContainer = dynamic_cast<PDFContainer*>(m_aObjectStack.back());
521 if( pContainer &&
522 ( dynamic_cast<PDFFile*>(pContainer) ||
523 dynamic_cast<PDFPart*>(pContainer) ) )
525 pContainer->m_aSubElements.push_back( pTrailer );
526 m_aObjectStack.push_back( pTrailer );
528 else
529 parseError( "trailer in wrong place", first );
532 void endTrailer( iteratorT first, SAL_UNUSED_PARAMETER iteratorT )
534 if( m_aObjectStack.empty() )
535 parseError( "%%EOF without trailer", first );
536 else if( dynamic_cast<PDFTrailer*>(m_aObjectStack.back()) == NULL )
537 parseError( "spurious %%EOF", first );
538 else
539 m_aObjectStack.pop_back();
543 #ifdef WIN32
544 PDFEntry* PDFReader::read( const char* pBuffer, unsigned int nLen )
546 PDFGrammar<const char*> aGrammar( pBuffer );
550 #if OSL_DEBUG_LEVEL > 1
551 boost::spirit::parse_info<const char*> aInfo =
552 #endif
553 boost::spirit::parse( pBuffer,
554 pBuffer+nLen,
555 aGrammar,
556 boost::spirit::space_p );
557 #if OSL_DEBUG_LEVEL > 1
558 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 = " << (int)aInfo.length );
559 #endif
561 catch( const parser_error<const char*, const char*>& rError )
563 #if OSL_DEBUG_LEVEL > 1
564 OString aTmp;
565 unsigned int nElem = aGrammar.m_aObjectStack.size();
566 for( unsigned int i = 0; i < nElem; i++ )
567 aTmp += " " + OString(typeid( *(aGrammar.m_aObjectStack[i]) ).name());
569 SAL_WARN("sdext.pdfimport.pdfparse", "parse error: " << rError.descriptor << " at buffer pos " << rError.where - pBuffer << ", object stack: " << aTmp);
570 #endif
573 PDFEntry* pRet = NULL;
574 unsigned int nEntries = aGrammar.m_aObjectStack.size();
575 if( nEntries == 1 )
577 pRet = aGrammar.m_aObjectStack.back();
578 aGrammar.m_aObjectStack.pop_back();
580 #if OSL_DEBUG_LEVEL > 1
581 else if( nEntries > 1 )
582 SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries << " stack objects in parse" );
583 #endif
585 return pRet;
587 #endif
589 PDFEntry* PDFReader::read( const char* pFileName )
591 #ifdef WIN32
592 /* #i106583#
593 since converting to boost 1.39 file_iterator does not work anymore on all Windows systems
594 C++ stdlib istream_iterator does not allow "-" apparently
595 using spirit 2.0 doesn't work in our environment with the MSC
597 So for the time being bite the bullet and read the whole file.
598 FIXME: give Spirit 2.x another try when we upgrade boost again.
600 PDFEntry* pRet = NULL;
601 FILE* fp = fopen( pFileName, "rb" );
602 if( fp )
604 fseek( fp, 0, SEEK_END );
605 unsigned int nLen = (unsigned int)ftell( fp );
606 fseek( fp, 0, SEEK_SET );
607 char* pBuf = (char*)rtl_allocateMemory( nLen );
608 if( pBuf )
610 fread( pBuf, 1, nLen, fp );
611 pRet = read( pBuf, nLen );
612 rtl_freeMemory( pBuf );
614 fclose( fp );
616 return pRet;
617 #else
618 file_iterator<> file_start( pFileName );
619 if( ! file_start )
620 return NULL;
621 file_iterator<> file_end = file_start.make_end();
622 PDFGrammar< file_iterator<> > aGrammar( file_start );
626 #if OSL_DEBUG_LEVEL > 1
627 boost::spirit::parse_info< file_iterator<> > aInfo =
628 #endif
629 boost::spirit::parse( file_start,
630 file_end,
631 aGrammar,
632 boost::spirit::space_p );
633 #if OSL_DEBUG_LEVEL > 1
634 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);
635 #endif
637 catch( const parser_error< const char*, file_iterator<> >& rError )
639 SAL_WARN("sdext.pdfimport.pdfparse", "parse error: " << rError.descriptor << " at buffer pos " << rError.where - file_start);
640 #if OSL_DEBUG_LEVEL > 1
641 OUString aTmp;
642 unsigned int nElem = aGrammar.m_aObjectStack.size();
643 for( unsigned int i = 0; i < nElem; i++ )
645 aTmp += " ";
646 aTmp += OUString(typeid( *(aGrammar.m_aObjectStack[i]) ).name(),
647 strlen(typeid( *(aGrammar.m_aObjectStack[i]) ).name()),
648 RTL_TEXTENCODING_ASCII_US);
650 SAL_WARN("sdext.pdfimport.pdfparse", "parse error object stack: " << aTmp);
651 #endif
654 PDFEntry* pRet = NULL;
655 unsigned int nEntries = aGrammar.m_aObjectStack.size();
656 if( nEntries == 1 )
658 pRet = aGrammar.m_aObjectStack.back();
659 aGrammar.m_aObjectStack.pop_back();
661 #if OSL_DEBUG_LEVEL > 1
662 else if( nEntries > 1 )
664 SAL_WARN("sdext.pdfimport.pdfparse", "error got " << nEntries << " stack objects in parse");
665 for( unsigned int i = 0; i < nEntries; i++ )
667 SAL_WARN("sdext.pdfimport.pdfparse", typeid(*aGrammar.m_aObjectStack[i]).name());
668 PDFObject* pObj = dynamic_cast<PDFObject*>(aGrammar.m_aObjectStack[i]);
669 if( pObj )
670 SAL_WARN("sdext.pdfimport.pdfparse", " -> object " << pObj->m_nNumber << " generation " << pObj->m_nGeneration);
671 else
672 SAL_WARN("sdext.pdfimport.pdfparse", "(type " << typeid(*aGrammar.m_aObjectStack[i]).name() << ")");
675 #endif
676 return pRet;
677 #endif // WIN32
680 #if defined _MSC_VER
681 #pragma warning(pop)
682 #endif
685 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */