1c142477cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3c142477cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4c142477cSAndrew Rist * or more contributor license agreements. See the NOTICE file
5c142477cSAndrew Rist * distributed with this work for additional information
6c142477cSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7c142477cSAndrew Rist * to you under the Apache License, Version 2.0 (the
8c142477cSAndrew Rist * "License"); you may not use this file except in compliance
9c142477cSAndrew Rist * with the License. You may obtain a copy of the License at
10c142477cSAndrew Rist *
11c142477cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12c142477cSAndrew Rist *
13c142477cSAndrew Rist * Unless required by applicable law or agreed to in writing,
14c142477cSAndrew Rist * software distributed under the License is distributed on an
15c142477cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c142477cSAndrew Rist * KIND, either express or implied. See the License for the
17c142477cSAndrew Rist * specific language governing permissions and limitations
18c142477cSAndrew Rist * under the License.
19c142477cSAndrew Rist *
20c142477cSAndrew Rist *************************************************************/
21c142477cSAndrew Rist
22c142477cSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sdext.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <pdfparse.hxx>
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include <rtl/strbuf.hxx>
30cdf0e10cSrcweir #include <rtl/ustring.hxx>
31cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
32cdf0e10cSrcweir #include <rtl/alloc.h>
33cdf0e10cSrcweir #include <rtl/digest.h>
34cdf0e10cSrcweir #include <rtl/cipher.h>
35cdf0e10cSrcweir #include <rtl/memory.h>
36cdf0e10cSrcweir #ifdef SYSTEM_ZLIB
37cdf0e10cSrcweir #include "zlib.h"
38cdf0e10cSrcweir #else
39cdf0e10cSrcweir #include <zlib/zlib.h>
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir
42cdf0e10cSrcweir #include <math.h>
43cdf0e10cSrcweir #include <map>
44cdf0e10cSrcweir
45cdf0e10cSrcweir #include <stdio.h>
46cdf0e10cSrcweir
47cdf0e10cSrcweir using namespace rtl;
48cdf0e10cSrcweir
49cdf0e10cSrcweir namespace pdfparse
50cdf0e10cSrcweir {
51cdf0e10cSrcweir
52cdf0e10cSrcweir struct EmitImplData
53cdf0e10cSrcweir {
54cdf0e10cSrcweir // xref table: maps object number to a pair of (generation, buffer offset)
55cdf0e10cSrcweir typedef std::map< unsigned int, std::pair< unsigned int, unsigned int > > XRefTable;
56cdf0e10cSrcweir XRefTable m_aXRefTable;
57cdf0e10cSrcweir // container of all indirect objects (usually a PDFFile*)
58cdf0e10cSrcweir const PDFContainer* m_pObjectContainer;
59cdf0e10cSrcweir unsigned int m_nDecryptObject;
60cdf0e10cSrcweir unsigned int m_nDecryptGeneration;
61cdf0e10cSrcweir
62cdf0e10cSrcweir // returns true if the xref table was updated
insertXrefpdfparse::EmitImplData63cdf0e10cSrcweir bool insertXref( unsigned int nObject, unsigned int nGeneration, unsigned int nOffset )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir XRefTable::iterator it = m_aXRefTable.find( nObject );
66cdf0e10cSrcweir if( it == m_aXRefTable.end() )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir // new entry
69cdf0e10cSrcweir m_aXRefTable[ nObject ] = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
70cdf0e10cSrcweir return true;
71cdf0e10cSrcweir }
72cdf0e10cSrcweir // update old entry, if generation number is higher
73cdf0e10cSrcweir if( it->second.first < nGeneration )
74cdf0e10cSrcweir {
75cdf0e10cSrcweir it->second = std::pair<unsigned int, unsigned int>(nGeneration,nOffset);
76cdf0e10cSrcweir return true;
77cdf0e10cSrcweir }
78cdf0e10cSrcweir return false;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir
EmitImplDatapdfparse::EmitImplData81cdf0e10cSrcweir EmitImplData( const PDFContainer* pTopContainer ) :
82cdf0e10cSrcweir m_pObjectContainer( pTopContainer ),
83cdf0e10cSrcweir m_nDecryptObject( 0 ),
84cdf0e10cSrcweir m_nDecryptGeneration( 0 )
85cdf0e10cSrcweir {}
~EmitImplDatapdfparse::EmitImplData86cdf0e10cSrcweir ~EmitImplData() {}
decryptpdfparse::EmitImplData87cdf0e10cSrcweir bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
88cdf0e10cSrcweir unsigned int nObject, unsigned int nGeneration ) const
89cdf0e10cSrcweir {
90cdf0e10cSrcweir const PDFFile* pFile = dynamic_cast<const PDFFile*>(m_pObjectContainer);
91cdf0e10cSrcweir return pFile ? pFile->decrypt( pInBuffer, nLen, pOutBuffer, nObject, nGeneration ) : false;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir
setDecryptObjectpdfparse::EmitImplData94cdf0e10cSrcweir void setDecryptObject( unsigned int nObject, unsigned int nGeneration )
95cdf0e10cSrcweir {
96cdf0e10cSrcweir m_nDecryptObject = nObject;
97cdf0e10cSrcweir m_nDecryptGeneration = nGeneration;
98cdf0e10cSrcweir }
99cdf0e10cSrcweir };
100cdf0e10cSrcweir
101cdf0e10cSrcweir }
102cdf0e10cSrcweir
103cdf0e10cSrcweir using namespace pdfparse;
104cdf0e10cSrcweir
EmitContext(const PDFContainer * pTop)105cdf0e10cSrcweir EmitContext::EmitContext( const PDFContainer* pTop ) :
106cdf0e10cSrcweir m_bDeflate( false ),
107cdf0e10cSrcweir m_bDecrypt( false ),
108cdf0e10cSrcweir m_pImplData( NULL )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir if( pTop )
111cdf0e10cSrcweir m_pImplData = new EmitImplData( pTop );
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
~EmitContext()114cdf0e10cSrcweir EmitContext::~EmitContext()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir delete m_pImplData;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
~PDFEntry()119cdf0e10cSrcweir PDFEntry::~PDFEntry()
120cdf0e10cSrcweir {
121cdf0e10cSrcweir }
122cdf0e10cSrcweir
getEmitData(EmitContext & rContext) const123cdf0e10cSrcweir EmitImplData* PDFEntry::getEmitData( EmitContext& rContext ) const
124cdf0e10cSrcweir {
125cdf0e10cSrcweir return rContext.m_pImplData;
126cdf0e10cSrcweir }
127cdf0e10cSrcweir
setEmitData(EmitContext & rContext,EmitImplData * pNewEmitData) const128cdf0e10cSrcweir void PDFEntry::setEmitData( EmitContext& rContext, EmitImplData* pNewEmitData ) const
129cdf0e10cSrcweir {
130cdf0e10cSrcweir if( rContext.m_pImplData && rContext.m_pImplData != pNewEmitData )
131cdf0e10cSrcweir delete rContext.m_pImplData;
132cdf0e10cSrcweir rContext.m_pImplData = pNewEmitData;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
~PDFValue()135cdf0e10cSrcweir PDFValue::~PDFValue()
136cdf0e10cSrcweir {
137cdf0e10cSrcweir }
138cdf0e10cSrcweir
~PDFComment()139cdf0e10cSrcweir PDFComment::~PDFComment()
140cdf0e10cSrcweir {
141cdf0e10cSrcweir }
142cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const143cdf0e10cSrcweir bool PDFComment::emit( EmitContext& rWriteContext ) const
144cdf0e10cSrcweir {
145cdf0e10cSrcweir return rWriteContext.write( m_aComment.getStr(), m_aComment.getLength() );
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
clone() const148cdf0e10cSrcweir PDFEntry* PDFComment::clone() const
149cdf0e10cSrcweir {
150cdf0e10cSrcweir return new PDFComment( m_aComment );
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
~PDFName()153cdf0e10cSrcweir PDFName::~PDFName()
154cdf0e10cSrcweir {
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const157cdf0e10cSrcweir bool PDFName::emit( EmitContext& rWriteContext ) const
158cdf0e10cSrcweir {
159cdf0e10cSrcweir if( ! rWriteContext.write( " /", 2 ) )
160cdf0e10cSrcweir return false;
161cdf0e10cSrcweir return rWriteContext.write( m_aName.getStr(), m_aName.getLength() );
162cdf0e10cSrcweir }
163cdf0e10cSrcweir
clone() const164cdf0e10cSrcweir PDFEntry* PDFName::clone() const
165cdf0e10cSrcweir {
166cdf0e10cSrcweir return new PDFName( m_aName );
167cdf0e10cSrcweir }
168cdf0e10cSrcweir
getFilteredName() const169cdf0e10cSrcweir OUString PDFName::getFilteredName() const
170cdf0e10cSrcweir {
171cdf0e10cSrcweir OStringBuffer aFilter( m_aName.getLength() );
172cdf0e10cSrcweir const sal_Char* pStr = m_aName.getStr();
173cdf0e10cSrcweir unsigned int nLen = m_aName.getLength();
174cdf0e10cSrcweir for( unsigned int i = 0; i < nLen; i++ )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir if( pStr[i] == '#' && i < nLen - 3 )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir sal_Char rResult = 0;
179cdf0e10cSrcweir i++;
180cdf0e10cSrcweir if( pStr[i] >= '0' && pStr[i] <= '9' )
181cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'0' ) << 4;
182cdf0e10cSrcweir else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
183cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'a' + 10 ) << 4;
184cdf0e10cSrcweir else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
185cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'A' + 10 ) << 4;
186cdf0e10cSrcweir i++;
187cdf0e10cSrcweir if( pStr[i] >= '0' && pStr[i] <= '9' )
188cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'0' );
189cdf0e10cSrcweir else if( pStr[i] >= 'a' && pStr[i] <= 'f' )
190cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'a' + 10 );
191cdf0e10cSrcweir else if( pStr[i] >= 'A' && pStr[i] <= 'F' )
192cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'A' + 10 );
193cdf0e10cSrcweir aFilter.append( rResult );
194cdf0e10cSrcweir }
195cdf0e10cSrcweir else
196cdf0e10cSrcweir aFilter.append( pStr[i] );
197cdf0e10cSrcweir }
198cdf0e10cSrcweir return OStringToOUString( aFilter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
199cdf0e10cSrcweir }
200cdf0e10cSrcweir
~PDFString()201cdf0e10cSrcweir PDFString::~PDFString()
202cdf0e10cSrcweir {
203cdf0e10cSrcweir }
204cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const205cdf0e10cSrcweir bool PDFString::emit( EmitContext& rWriteContext ) const
206cdf0e10cSrcweir {
207cdf0e10cSrcweir if( ! rWriteContext.write( " ", 1 ) )
208cdf0e10cSrcweir return false;
209cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext );
210cdf0e10cSrcweir if( rWriteContext.m_bDecrypt && pEData && pEData->m_nDecryptObject )
211cdf0e10cSrcweir {
212cdf0e10cSrcweir OString aFiltered( getFilteredString() );
213cdf0e10cSrcweir // decrypt inplace (evil since OString is supposed to be const
214cdf0e10cSrcweir // however in this case we know that getFilteredString returned a singular string instance
215cdf0e10cSrcweir pEData->decrypt( (sal_uInt8*)aFiltered.getStr(), aFiltered.getLength(),
216cdf0e10cSrcweir (sal_uInt8*)aFiltered.getStr(),
217cdf0e10cSrcweir pEData->m_nDecryptObject, pEData->m_nDecryptGeneration );
218cdf0e10cSrcweir // check for string or hex string
219cdf0e10cSrcweir const sal_Char* pStr = aFiltered.getStr();
220cdf0e10cSrcweir if( aFiltered.getLength() > 1 &&
221cdf0e10cSrcweir ( (pStr[0] == sal_Char(0xff) && pStr[1] == sal_Char(0xfe)) ||
222cdf0e10cSrcweir (pStr[0] == sal_Char(0xfe) && pStr[1] == sal_Char(0xff)) ) )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir static const char pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
225cdf0e10cSrcweir '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
226cdf0e10cSrcweir if( ! rWriteContext.write( "<", 1 ) )
227cdf0e10cSrcweir return false;
228cdf0e10cSrcweir for( sal_Int32 i = 0; i < aFiltered.getLength(); i++ )
229cdf0e10cSrcweir {
230cdf0e10cSrcweir if( ! rWriteContext.write( pHexTab + ((sal_uInt32(pStr[i]) >> 4) & 0x0f), 1 ) )
231cdf0e10cSrcweir return false;
232cdf0e10cSrcweir if( ! rWriteContext.write( pHexTab + (sal_uInt32(pStr[i]) & 0x0f), 1 ) )
233cdf0e10cSrcweir return false;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir if( ! rWriteContext.write( ">", 1 ) )
236cdf0e10cSrcweir return false;
237cdf0e10cSrcweir }
238cdf0e10cSrcweir else
239cdf0e10cSrcweir {
240cdf0e10cSrcweir if( ! rWriteContext.write( "(", 1 ) )
241cdf0e10cSrcweir return false;
242cdf0e10cSrcweir if( ! rWriteContext.write( aFiltered.getStr(), aFiltered.getLength() ) )
243cdf0e10cSrcweir return false;
244cdf0e10cSrcweir if( ! rWriteContext.write( ")", 1 ) )
245cdf0e10cSrcweir return false;
246cdf0e10cSrcweir }
247cdf0e10cSrcweir return true;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir return rWriteContext.write( m_aString.getStr(), m_aString.getLength() );
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
clone() const252cdf0e10cSrcweir PDFEntry* PDFString::clone() const
253cdf0e10cSrcweir {
254cdf0e10cSrcweir return new PDFString( m_aString );
255cdf0e10cSrcweir }
256cdf0e10cSrcweir
getFilteredString() const257cdf0e10cSrcweir OString PDFString::getFilteredString() const
258cdf0e10cSrcweir {
259cdf0e10cSrcweir int nLen = m_aString.getLength();
260cdf0e10cSrcweir OStringBuffer aBuf( nLen );
261cdf0e10cSrcweir
262cdf0e10cSrcweir const sal_Char* pStr = m_aString.getStr();
263cdf0e10cSrcweir if( *pStr == '(' )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir const sal_Char* pRun = pStr+1;
266cdf0e10cSrcweir while( pRun - pStr < nLen-1 )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir if( *pRun == '\\' )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir pRun++;
271cdf0e10cSrcweir if( pRun - pStr < nLen )
272cdf0e10cSrcweir {
273cdf0e10cSrcweir sal_Char aEsc = 0;
274cdf0e10cSrcweir if( *pRun == 'n' )
275cdf0e10cSrcweir aEsc = '\n';
276cdf0e10cSrcweir else if( *pRun == 'r' )
277cdf0e10cSrcweir aEsc = '\r';
278cdf0e10cSrcweir else if( *pRun == 't' )
279cdf0e10cSrcweir aEsc = '\t';
280cdf0e10cSrcweir else if( *pRun == 'b' )
281cdf0e10cSrcweir aEsc = '\b';
282cdf0e10cSrcweir else if( *pRun == 'f' )
283cdf0e10cSrcweir aEsc = '\f';
284cdf0e10cSrcweir else if( *pRun == '(' )
285cdf0e10cSrcweir aEsc = '(';
286cdf0e10cSrcweir else if( *pRun == ')' )
287cdf0e10cSrcweir aEsc = ')';
288cdf0e10cSrcweir else if( *pRun == '\\' )
289cdf0e10cSrcweir aEsc = '\\';
290cdf0e10cSrcweir else if( *pRun == '\n' )
291cdf0e10cSrcweir {
292cdf0e10cSrcweir pRun++;
293cdf0e10cSrcweir continue;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir else if( *pRun == '\r' )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir pRun++;
298cdf0e10cSrcweir if( *pRun == '\n' )
299cdf0e10cSrcweir pRun++;
300cdf0e10cSrcweir continue;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir else
303cdf0e10cSrcweir {
304cdf0e10cSrcweir int i = 0;
305cdf0e10cSrcweir while( i++ < 3 && *pRun >= '0' && *pRun <= '7' )
306cdf0e10cSrcweir aEsc = 8*aEsc + (*pRun++ - '0');
307cdf0e10cSrcweir // move pointer back to last character of octal sequence
308cdf0e10cSrcweir pRun--;
309cdf0e10cSrcweir }
310cdf0e10cSrcweir aBuf.append( aEsc );
311cdf0e10cSrcweir }
312cdf0e10cSrcweir }
313cdf0e10cSrcweir else
314cdf0e10cSrcweir aBuf.append( *pRun );
315cdf0e10cSrcweir // move pointer to next character
316cdf0e10cSrcweir pRun++;
317cdf0e10cSrcweir }
318cdf0e10cSrcweir }
319cdf0e10cSrcweir else if( *pStr == '<' )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir const sal_Char* pRun = pStr+1;
322cdf0e10cSrcweir while( *pRun != '>' && pRun - pStr < nLen )
323cdf0e10cSrcweir {
324cdf0e10cSrcweir sal_Char rResult = 0;
325cdf0e10cSrcweir if( *pRun >= '0' && *pRun <= '9' )
326cdf0e10cSrcweir rResult = sal_Char( *pRun-'0' ) << 4;
327cdf0e10cSrcweir else if( *pRun >= 'a' && *pRun <= 'f' )
328cdf0e10cSrcweir rResult = sal_Char( *pRun-'a' + 10 ) << 4;
329cdf0e10cSrcweir else if( *pRun >= 'A' && *pRun <= 'F' )
330cdf0e10cSrcweir rResult = sal_Char( *pRun-'A' + 10 ) << 4;
331cdf0e10cSrcweir pRun++;
332cdf0e10cSrcweir if( *pRun != '>' && pRun - pStr < nLen )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir if( *pRun >= '0' && *pRun <= '9' )
335cdf0e10cSrcweir rResult |= sal_Char( *pRun-'0' );
336cdf0e10cSrcweir else if( *pRun >= 'a' && *pRun <= 'f' )
337cdf0e10cSrcweir rResult |= sal_Char( *pRun-'a' + 10 );
338cdf0e10cSrcweir else if( *pRun >= 'A' && *pRun <= 'F' )
339cdf0e10cSrcweir rResult |= sal_Char( *pRun-'A' + 10 );
340cdf0e10cSrcweir }
341cdf0e10cSrcweir pRun++;
342cdf0e10cSrcweir aBuf.append( rResult );
343cdf0e10cSrcweir }
344cdf0e10cSrcweir }
345cdf0e10cSrcweir
346cdf0e10cSrcweir return aBuf.makeStringAndClear();
347cdf0e10cSrcweir }
348cdf0e10cSrcweir
~PDFNumber()349cdf0e10cSrcweir PDFNumber::~PDFNumber()
350cdf0e10cSrcweir {
351cdf0e10cSrcweir }
352cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const353cdf0e10cSrcweir bool PDFNumber::emit( EmitContext& rWriteContext ) const
354cdf0e10cSrcweir {
355cdf0e10cSrcweir rtl::OStringBuffer aBuf( 32 );
356cdf0e10cSrcweir aBuf.append( ' ' );
357cdf0e10cSrcweir
358cdf0e10cSrcweir double fValue = m_fValue;
359cdf0e10cSrcweir bool bNeg = false;
360cdf0e10cSrcweir int nPrecision = 5;
361cdf0e10cSrcweir if( fValue < 0.0 )
362cdf0e10cSrcweir {
363cdf0e10cSrcweir bNeg = true;
364cdf0e10cSrcweir fValue=-fValue;
365cdf0e10cSrcweir }
366cdf0e10cSrcweir
367cdf0e10cSrcweir sal_Int64 nInt = (sal_Int64)fValue;
368cdf0e10cSrcweir fValue -= (double)nInt;
369cdf0e10cSrcweir // optimizing hardware may lead to a value of 1.0 after the subtraction
370cdf0e10cSrcweir if( fValue == 1.0 || log10( 1.0-fValue ) <= -nPrecision )
371cdf0e10cSrcweir {
372cdf0e10cSrcweir nInt++;
373cdf0e10cSrcweir fValue = 0.0;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir sal_Int64 nFrac = 0;
376cdf0e10cSrcweir if( fValue )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir fValue *= pow( 10.0, (double)nPrecision );
379cdf0e10cSrcweir nFrac = (sal_Int64)fValue;
380cdf0e10cSrcweir }
381cdf0e10cSrcweir if( bNeg && ( nInt || nFrac ) )
382cdf0e10cSrcweir aBuf.append( '-' );
383cdf0e10cSrcweir aBuf.append( nInt );
384cdf0e10cSrcweir if( nFrac )
385cdf0e10cSrcweir {
386cdf0e10cSrcweir int i;
387cdf0e10cSrcweir aBuf.append( '.' );
388cdf0e10cSrcweir sal_Int64 nBound = (sal_Int64)(pow( 10.0, nPrecision - 1.0 )+0.5);
389cdf0e10cSrcweir for ( i = 0; ( i < nPrecision ) && nFrac; i++ )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir sal_Int64 nNumb = nFrac / nBound;
392cdf0e10cSrcweir nFrac -= nNumb * nBound;
393cdf0e10cSrcweir aBuf.append( nNumb );
394cdf0e10cSrcweir nBound /= 10;
395cdf0e10cSrcweir }
396cdf0e10cSrcweir }
397cdf0e10cSrcweir
398cdf0e10cSrcweir return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
clone() const401cdf0e10cSrcweir PDFEntry* PDFNumber::clone() const
402cdf0e10cSrcweir {
403cdf0e10cSrcweir return new PDFNumber( m_fValue );
404cdf0e10cSrcweir }
405cdf0e10cSrcweir
406cdf0e10cSrcweir
~PDFBool()407cdf0e10cSrcweir PDFBool::~PDFBool()
408cdf0e10cSrcweir {
409cdf0e10cSrcweir }
410cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const411cdf0e10cSrcweir bool PDFBool::emit( EmitContext& rWriteContext ) const
412cdf0e10cSrcweir {
413cdf0e10cSrcweir return m_bValue ? rWriteContext.write( " true", 5 ) : rWriteContext.write( " false", 6 );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir
clone() const416cdf0e10cSrcweir PDFEntry* PDFBool::clone() const
417cdf0e10cSrcweir {
418cdf0e10cSrcweir return new PDFBool( m_bValue );
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
~PDFNull()421cdf0e10cSrcweir PDFNull::~PDFNull()
422cdf0e10cSrcweir {
423cdf0e10cSrcweir }
424cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const425cdf0e10cSrcweir bool PDFNull::emit( EmitContext& rWriteContext ) const
426cdf0e10cSrcweir {
427cdf0e10cSrcweir return rWriteContext.write( " null", 5 );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
clone() const430cdf0e10cSrcweir PDFEntry* PDFNull::clone() const
431cdf0e10cSrcweir {
432cdf0e10cSrcweir return new PDFNull();
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
435cdf0e10cSrcweir
~PDFObjectRef()436cdf0e10cSrcweir PDFObjectRef::~PDFObjectRef()
437cdf0e10cSrcweir {
438cdf0e10cSrcweir }
439cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const440cdf0e10cSrcweir bool PDFObjectRef::emit( EmitContext& rWriteContext ) const
441cdf0e10cSrcweir {
442cdf0e10cSrcweir OStringBuffer aBuf( 16 );
443cdf0e10cSrcweir aBuf.append( ' ' );
444cdf0e10cSrcweir aBuf.append( sal_Int32( m_nNumber ) );
445cdf0e10cSrcweir aBuf.append( ' ' );
446cdf0e10cSrcweir aBuf.append( sal_Int32( m_nGeneration ) );
447cdf0e10cSrcweir aBuf.append( " R", 2 );
448cdf0e10cSrcweir return rWriteContext.write( aBuf.getStr(), aBuf.getLength() );
449cdf0e10cSrcweir }
450cdf0e10cSrcweir
clone() const451cdf0e10cSrcweir PDFEntry* PDFObjectRef::clone() const
452cdf0e10cSrcweir {
453cdf0e10cSrcweir return new PDFObjectRef( m_nNumber, m_nGeneration );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir
~PDFContainer()456cdf0e10cSrcweir PDFContainer::~PDFContainer()
457cdf0e10cSrcweir {
458cdf0e10cSrcweir int nEle = m_aSubElements.size();
459cdf0e10cSrcweir for( int i = 0; i < nEle; i++ )
460cdf0e10cSrcweir delete m_aSubElements[i];
461cdf0e10cSrcweir }
462cdf0e10cSrcweir
emitSubElements(EmitContext & rWriteContext) const463cdf0e10cSrcweir bool PDFContainer::emitSubElements( EmitContext& rWriteContext ) const
464cdf0e10cSrcweir {
465cdf0e10cSrcweir int nEle = m_aSubElements.size();
466cdf0e10cSrcweir for( int i = 0; i < nEle; i++ )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir if( rWriteContext.m_bDecrypt )
469cdf0e10cSrcweir {
470cdf0e10cSrcweir const PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
471cdf0e10cSrcweir if( pName && pName->m_aName.equals( rtl::OString("Encrypt") ) )
472cdf0e10cSrcweir {
473cdf0e10cSrcweir i++;
474cdf0e10cSrcweir continue;
475cdf0e10cSrcweir }
476cdf0e10cSrcweir }
477cdf0e10cSrcweir if( ! m_aSubElements[i]->emit( rWriteContext ) )
478cdf0e10cSrcweir return false;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir return true;
481cdf0e10cSrcweir }
482cdf0e10cSrcweir
cloneSubElements(std::vector<PDFEntry * > & rNewSubElements) const483cdf0e10cSrcweir void PDFContainer::cloneSubElements( std::vector<PDFEntry*>& rNewSubElements ) const
484cdf0e10cSrcweir {
485cdf0e10cSrcweir int nEle = m_aSubElements.size();
486cdf0e10cSrcweir for( int i = 0; i < nEle; i++ )
487cdf0e10cSrcweir rNewSubElements.push_back( m_aSubElements[i]->clone() );
488cdf0e10cSrcweir }
489cdf0e10cSrcweir
findObject(unsigned int nNumber,unsigned int nGeneration) const490cdf0e10cSrcweir PDFObject* PDFContainer::findObject( unsigned int nNumber, unsigned int nGeneration ) const
491cdf0e10cSrcweir {
492cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size();
493cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir PDFObject* pObject = dynamic_cast<PDFObject*>(m_aSubElements[i]);
496cdf0e10cSrcweir if( pObject &&
497cdf0e10cSrcweir pObject->m_nNumber == nNumber &&
498cdf0e10cSrcweir pObject->m_nGeneration == nGeneration )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir return pObject;
501cdf0e10cSrcweir }
502cdf0e10cSrcweir }
503cdf0e10cSrcweir return NULL;
504cdf0e10cSrcweir }
505cdf0e10cSrcweir
~PDFArray()506cdf0e10cSrcweir PDFArray::~PDFArray()
507cdf0e10cSrcweir {
508cdf0e10cSrcweir }
509cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const510cdf0e10cSrcweir bool PDFArray::emit( EmitContext& rWriteContext ) const
511cdf0e10cSrcweir {
512cdf0e10cSrcweir if( ! rWriteContext.write( "[", 1 ) )
513cdf0e10cSrcweir return false;
514cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) )
515cdf0e10cSrcweir return false;
516cdf0e10cSrcweir return rWriteContext.write( "]", 1 );
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
clone() const519cdf0e10cSrcweir PDFEntry* PDFArray::clone() const
520cdf0e10cSrcweir {
521cdf0e10cSrcweir PDFArray* pNewAr = new PDFArray();
522cdf0e10cSrcweir cloneSubElements( pNewAr->m_aSubElements );
523cdf0e10cSrcweir return pNewAr;
524cdf0e10cSrcweir }
525cdf0e10cSrcweir
~PDFDict()526cdf0e10cSrcweir PDFDict::~PDFDict()
527cdf0e10cSrcweir {
528cdf0e10cSrcweir }
529cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const530cdf0e10cSrcweir bool PDFDict::emit( EmitContext& rWriteContext ) const
531cdf0e10cSrcweir {
532cdf0e10cSrcweir if( ! rWriteContext.write( "<<\n", 3 ) )
533cdf0e10cSrcweir return false;
534cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) )
535cdf0e10cSrcweir return false;
536cdf0e10cSrcweir return rWriteContext.write( "\n>>\n", 4 );
537cdf0e10cSrcweir }
538cdf0e10cSrcweir
insertValue(const OString & rName,PDFEntry * pValue)539cdf0e10cSrcweir void PDFDict::insertValue( const OString& rName, PDFEntry* pValue )
540cdf0e10cSrcweir {
541cdf0e10cSrcweir if( ! pValue )
542cdf0e10cSrcweir eraseValue( rName );
543cdf0e10cSrcweir
544cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::iterator it = m_aMap.find( rName );
545cdf0e10cSrcweir if( it == m_aMap.end() )
546cdf0e10cSrcweir {
547cdf0e10cSrcweir // new name/value, pair, append it
548cdf0e10cSrcweir m_aSubElements.push_back( new PDFName( rName ) );
549cdf0e10cSrcweir m_aSubElements.push_back( pValue );
550cdf0e10cSrcweir }
551cdf0e10cSrcweir else
552cdf0e10cSrcweir {
553cdf0e10cSrcweir unsigned int nSub = m_aSubElements.size();
554cdf0e10cSrcweir for( unsigned int i = 0; i < nSub; i++ )
555cdf0e10cSrcweir if( m_aSubElements[i] == it->second )
556cdf0e10cSrcweir m_aSubElements[i] = pValue;
557cdf0e10cSrcweir delete it->second;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir m_aMap[ rName ] = pValue;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir
eraseValue(const OString & rName)562cdf0e10cSrcweir void PDFDict::eraseValue( const OString& rName )
563cdf0e10cSrcweir {
564cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size();
565cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ )
566cdf0e10cSrcweir {
567cdf0e10cSrcweir PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
568cdf0e10cSrcweir if( pName && pName->m_aName.equals( rName ) )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir for( unsigned int j = i+1; j < nEle; j++ )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir if( dynamic_cast<PDFComment*>(m_aSubElements[j]) == NULL )
573cdf0e10cSrcweir {
574cdf0e10cSrcweir // free name and value
575cdf0e10cSrcweir delete m_aSubElements[j];
576cdf0e10cSrcweir delete m_aSubElements[i];
577cdf0e10cSrcweir // remove subelements from vector
578cdf0e10cSrcweir m_aSubElements.erase( m_aSubElements.begin()+j );
579cdf0e10cSrcweir m_aSubElements.erase( m_aSubElements.begin()+i );
580cdf0e10cSrcweir buildMap();
581cdf0e10cSrcweir return;
582cdf0e10cSrcweir }
583cdf0e10cSrcweir }
584cdf0e10cSrcweir }
585cdf0e10cSrcweir }
586cdf0e10cSrcweir }
587cdf0e10cSrcweir
buildMap()588cdf0e10cSrcweir PDFEntry* PDFDict::buildMap()
589cdf0e10cSrcweir {
590cdf0e10cSrcweir // clear map
591cdf0e10cSrcweir m_aMap.clear();
592cdf0e10cSrcweir // build map
593cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size();
594cdf0e10cSrcweir PDFName* pName = NULL;
595cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ )
596cdf0e10cSrcweir {
597cdf0e10cSrcweir if( dynamic_cast<PDFComment*>(m_aSubElements[i]) == NULL )
598cdf0e10cSrcweir {
599cdf0e10cSrcweir if( pName )
600cdf0e10cSrcweir {
601cdf0e10cSrcweir m_aMap[ pName->m_aName ] = m_aSubElements[i];
602cdf0e10cSrcweir pName = NULL;
603cdf0e10cSrcweir }
604cdf0e10cSrcweir else if( (pName = dynamic_cast<PDFName*>(m_aSubElements[i])) == NULL )
605cdf0e10cSrcweir return m_aSubElements[i];
606cdf0e10cSrcweir }
607cdf0e10cSrcweir }
608cdf0e10cSrcweir return pName;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir
clone() const611cdf0e10cSrcweir PDFEntry* PDFDict::clone() const
612cdf0e10cSrcweir {
613cdf0e10cSrcweir PDFDict* pNewDict = new PDFDict();
614cdf0e10cSrcweir cloneSubElements( pNewDict->m_aSubElements );
615cdf0e10cSrcweir pNewDict->buildMap();
616cdf0e10cSrcweir return pNewDict;
617cdf0e10cSrcweir }
618cdf0e10cSrcweir
~PDFStream()619cdf0e10cSrcweir PDFStream::~PDFStream()
620cdf0e10cSrcweir {
621cdf0e10cSrcweir }
622cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const623cdf0e10cSrcweir bool PDFStream::emit( EmitContext& rWriteContext ) const
624cdf0e10cSrcweir {
625cdf0e10cSrcweir return rWriteContext.copyOrigBytes( m_nBeginOffset, m_nEndOffset-m_nBeginOffset );
626cdf0e10cSrcweir }
627cdf0e10cSrcweir
clone() const628cdf0e10cSrcweir PDFEntry* PDFStream::clone() const
629cdf0e10cSrcweir {
630cdf0e10cSrcweir return new PDFStream( m_nBeginOffset, m_nEndOffset, NULL );
631cdf0e10cSrcweir }
632cdf0e10cSrcweir
getDictLength(const PDFContainer * pContainer) const633cdf0e10cSrcweir unsigned int PDFStream::getDictLength( const PDFContainer* pContainer ) const
634cdf0e10cSrcweir {
635cdf0e10cSrcweir if( ! m_pDict )
636cdf0e10cSrcweir return 0;
637cdf0e10cSrcweir // find /Length entry, can either be a direct or indirect number object
638cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
639cdf0e10cSrcweir m_pDict->m_aMap.find( "Length" );
640cdf0e10cSrcweir if( it == m_pDict->m_aMap.end() )
641cdf0e10cSrcweir return 0;
642cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(it->second);
643cdf0e10cSrcweir if( ! pNum && pContainer )
644cdf0e10cSrcweir {
645cdf0e10cSrcweir PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(it->second);
646cdf0e10cSrcweir if( pRef )
647cdf0e10cSrcweir {
648cdf0e10cSrcweir int nEle = pContainer->m_aSubElements.size();
649cdf0e10cSrcweir for( int i = 0; i < nEle && ! pNum; i++ )
650cdf0e10cSrcweir {
651cdf0e10cSrcweir PDFObject* pObj = dynamic_cast<PDFObject*>(pContainer->m_aSubElements[i]);
652cdf0e10cSrcweir if( pObj &&
653cdf0e10cSrcweir pObj->m_nNumber == pRef->m_nNumber &&
654cdf0e10cSrcweir pObj->m_nGeneration == pRef->m_nGeneration )
655cdf0e10cSrcweir {
656cdf0e10cSrcweir if( pObj->m_pObject )
657cdf0e10cSrcweir pNum = dynamic_cast<PDFNumber*>(pObj->m_pObject);
658cdf0e10cSrcweir break;
659cdf0e10cSrcweir }
660cdf0e10cSrcweir }
661cdf0e10cSrcweir }
662cdf0e10cSrcweir }
663cdf0e10cSrcweir return pNum ? static_cast<unsigned int>(pNum->m_fValue) : 0;
664cdf0e10cSrcweir }
665cdf0e10cSrcweir
~PDFObject()666cdf0e10cSrcweir PDFObject::~PDFObject()
667cdf0e10cSrcweir {
668cdf0e10cSrcweir }
669cdf0e10cSrcweir
getDeflatedStream(char ** ppStream,unsigned int * pBytes,const PDFContainer * pObjectContainer,EmitContext & rContext) const670cdf0e10cSrcweir bool PDFObject::getDeflatedStream( char** ppStream, unsigned int* pBytes, const PDFContainer* pObjectContainer, EmitContext& rContext ) const
671cdf0e10cSrcweir {
672cdf0e10cSrcweir bool bIsDeflated = false;
673cdf0e10cSrcweir if( m_pStream && m_pStream->m_pDict &&
674cdf0e10cSrcweir m_pStream->m_nEndOffset > m_pStream->m_nBeginOffset+15
675cdf0e10cSrcweir )
676cdf0e10cSrcweir {
677cdf0e10cSrcweir unsigned int nOuterStreamLen = m_pStream->m_nEndOffset - m_pStream->m_nBeginOffset;
678cdf0e10cSrcweir *ppStream = static_cast<char*>(rtl_allocateMemory( nOuterStreamLen ));
679cdf0e10cSrcweir if( ! ppStream )
680cdf0e10cSrcweir {
681cdf0e10cSrcweir *pBytes = 0;
682cdf0e10cSrcweir return false;
683cdf0e10cSrcweir }
684cdf0e10cSrcweir unsigned int nRead = rContext.readOrigBytes( m_pStream->m_nBeginOffset, nOuterStreamLen, *ppStream );
685cdf0e10cSrcweir if( nRead != nOuterStreamLen )
686cdf0e10cSrcweir {
687cdf0e10cSrcweir rtl_freeMemory( *ppStream );
688cdf0e10cSrcweir *ppStream = NULL;
689cdf0e10cSrcweir *pBytes = 0;
690cdf0e10cSrcweir return false;
691cdf0e10cSrcweir }
692cdf0e10cSrcweir // is there a filter entry ?
693cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
694cdf0e10cSrcweir m_pStream->m_pDict->m_aMap.find( "Filter" );
695cdf0e10cSrcweir if( it != m_pStream->m_pDict->m_aMap.end() )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
698cdf0e10cSrcweir if( ! pFilter )
699cdf0e10cSrcweir {
700cdf0e10cSrcweir PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
701cdf0e10cSrcweir if( pArray && ! pArray->m_aSubElements.empty() )
702cdf0e10cSrcweir {
703cdf0e10cSrcweir pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
704cdf0e10cSrcweir }
705cdf0e10cSrcweir }
706cdf0e10cSrcweir
707cdf0e10cSrcweir // is the (first) filter FlateDecode ?
708cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
709cdf0e10cSrcweir {
710cdf0e10cSrcweir bIsDeflated = true;
711cdf0e10cSrcweir }
712cdf0e10cSrcweir }
713cdf0e10cSrcweir // prepare compressed data section
714cdf0e10cSrcweir char* pStream = *ppStream;
715cdf0e10cSrcweir if( pStream[0] == 's' )
716cdf0e10cSrcweir pStream += 6; // skip "stream"
717cdf0e10cSrcweir // skip line end after "stream"
718cdf0e10cSrcweir while( *pStream == '\r' || *pStream == '\n' )
719cdf0e10cSrcweir pStream++;
720cdf0e10cSrcweir // get the compressed length
721cdf0e10cSrcweir *pBytes = m_pStream->getDictLength( pObjectContainer );
722cdf0e10cSrcweir if( pStream != *ppStream )
723cdf0e10cSrcweir rtl_moveMemory( *ppStream, pStream, *pBytes );
724cdf0e10cSrcweir if( rContext.m_bDecrypt )
725cdf0e10cSrcweir {
726cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rContext );
727cdf0e10cSrcweir pEData->decrypt( reinterpret_cast<const sal_uInt8*>(*ppStream),
728cdf0e10cSrcweir *pBytes,
729cdf0e10cSrcweir reinterpret_cast<sal_uInt8*>(*ppStream),
730cdf0e10cSrcweir m_nNumber,
731cdf0e10cSrcweir m_nGeneration
732cdf0e10cSrcweir ); // decrypt inplace
733cdf0e10cSrcweir }
734cdf0e10cSrcweir }
735cdf0e10cSrcweir else
736cdf0e10cSrcweir *ppStream = NULL, *pBytes = 0;
737cdf0e10cSrcweir return bIsDeflated;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir
unzipToBuffer(const char * pBegin,unsigned int nLen,sal_uInt8 ** pOutBuf,sal_uInt32 * pOutLen)740cdf0e10cSrcweir static void unzipToBuffer( const char* pBegin, unsigned int nLen,
741cdf0e10cSrcweir sal_uInt8** pOutBuf, sal_uInt32* pOutLen )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir z_stream aZStr;
744cdf0e10cSrcweir aZStr.next_in = (Bytef*)pBegin;
745cdf0e10cSrcweir aZStr.avail_in = nLen;
746cdf0e10cSrcweir aZStr.zalloc = ( alloc_func )0;
747cdf0e10cSrcweir aZStr.zfree = ( free_func )0;
748cdf0e10cSrcweir aZStr.opaque = ( voidpf )0;
749cdf0e10cSrcweir inflateInit(&aZStr);
750cdf0e10cSrcweir
751cdf0e10cSrcweir const unsigned int buf_increment_size = 16384;
752cdf0e10cSrcweir
753cdf0e10cSrcweir *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, buf_increment_size );
754cdf0e10cSrcweir aZStr.next_out = (Bytef*)*pOutBuf;
755cdf0e10cSrcweir aZStr.avail_out = buf_increment_size;
756cdf0e10cSrcweir int err = Z_OK;
757cdf0e10cSrcweir *pOutLen = buf_increment_size;
758cdf0e10cSrcweir while( err != Z_STREAM_END && err >= Z_OK && aZStr.avail_in )
759cdf0e10cSrcweir {
760cdf0e10cSrcweir err = inflate( &aZStr, Z_NO_FLUSH );
761cdf0e10cSrcweir if( aZStr.avail_out == 0 )
762cdf0e10cSrcweir {
763cdf0e10cSrcweir if( err != Z_STREAM_END )
764cdf0e10cSrcweir {
765cdf0e10cSrcweir const int nNewAlloc = *pOutLen + buf_increment_size;
766cdf0e10cSrcweir *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, nNewAlloc );
767cdf0e10cSrcweir aZStr.next_out = (Bytef*)(*pOutBuf + *pOutLen);
768cdf0e10cSrcweir aZStr.avail_out = buf_increment_size;
769cdf0e10cSrcweir *pOutLen = nNewAlloc;
770cdf0e10cSrcweir }
771cdf0e10cSrcweir }
772cdf0e10cSrcweir }
773cdf0e10cSrcweir if( err == Z_STREAM_END )
774cdf0e10cSrcweir {
775cdf0e10cSrcweir if( aZStr.avail_out > 0 )
776*0880834bSPedro Giffuni *pOutLen -= aZStr.avail_out;
777cdf0e10cSrcweir }
778cdf0e10cSrcweir inflateEnd(&aZStr);
779cdf0e10cSrcweir if( err < Z_OK )
780cdf0e10cSrcweir {
781cdf0e10cSrcweir rtl_freeMemory( *pOutBuf );
782cdf0e10cSrcweir *pOutBuf = NULL;
783cdf0e10cSrcweir *pOutLen = 0;
784cdf0e10cSrcweir }
785cdf0e10cSrcweir }
786cdf0e10cSrcweir
writeStream(EmitContext & rWriteContext,const PDFFile * pParsedFile) const787cdf0e10cSrcweir bool PDFObject::writeStream( EmitContext& rWriteContext, const PDFFile* pParsedFile ) const
788cdf0e10cSrcweir {
789cdf0e10cSrcweir bool bSuccess = false;
790cdf0e10cSrcweir if( m_pStream )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir char* pStream = NULL;
793cdf0e10cSrcweir unsigned int nBytes = 0;
794cdf0e10cSrcweir if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes && rWriteContext.m_bDeflate )
795cdf0e10cSrcweir {
796cdf0e10cSrcweir sal_uInt8* pOutBytes = NULL;
797cdf0e10cSrcweir sal_uInt32 nOutBytes = 0;
798cdf0e10cSrcweir unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
799cdf0e10cSrcweir rWriteContext.write( pOutBytes, nOutBytes );
800cdf0e10cSrcweir rtl_freeMemory( pOutBytes );
801cdf0e10cSrcweir }
802cdf0e10cSrcweir else if( pStream && nBytes )
803cdf0e10cSrcweir rWriteContext.write( pStream, nBytes );
804cdf0e10cSrcweir rtl_freeMemory( pStream );
805cdf0e10cSrcweir }
806cdf0e10cSrcweir return bSuccess;
807cdf0e10cSrcweir }
808cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const809cdf0e10cSrcweir bool PDFObject::emit( EmitContext& rWriteContext ) const
810cdf0e10cSrcweir {
811cdf0e10cSrcweir if( ! rWriteContext.write( "\n", 1 ) )
812cdf0e10cSrcweir return false;
813cdf0e10cSrcweir
814cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext );
815cdf0e10cSrcweir if( pEData )
816cdf0e10cSrcweir pEData->insertXref( m_nNumber, m_nGeneration, rWriteContext.getCurPos() );
817cdf0e10cSrcweir
818cdf0e10cSrcweir OStringBuffer aBuf( 32 );
819cdf0e10cSrcweir aBuf.append( sal_Int32( m_nNumber ) );
820cdf0e10cSrcweir aBuf.append( ' ' );
821cdf0e10cSrcweir aBuf.append( sal_Int32( m_nGeneration ) );
822cdf0e10cSrcweir aBuf.append( " obj\n" );
823cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
824cdf0e10cSrcweir return false;
825cdf0e10cSrcweir
826cdf0e10cSrcweir if( pEData )
827cdf0e10cSrcweir pEData->setDecryptObject( m_nNumber, m_nGeneration );
828cdf0e10cSrcweir if( (rWriteContext.m_bDeflate || rWriteContext.m_bDecrypt) && pEData )
829cdf0e10cSrcweir {
830cdf0e10cSrcweir char* pStream = NULL;
831cdf0e10cSrcweir unsigned int nBytes = 0;
832cdf0e10cSrcweir bool bDeflate = getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext );
833cdf0e10cSrcweir if( pStream && nBytes )
834cdf0e10cSrcweir {
835cdf0e10cSrcweir // unzip the stream
836cdf0e10cSrcweir sal_uInt8* pOutBytes = NULL;
837cdf0e10cSrcweir sal_uInt32 nOutBytes = 0;
838cdf0e10cSrcweir if( bDeflate && rWriteContext.m_bDeflate )
839cdf0e10cSrcweir unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
840cdf0e10cSrcweir else
841cdf0e10cSrcweir {
842cdf0e10cSrcweir // nothing to deflate, but decryption has happened
843cdf0e10cSrcweir pOutBytes = (sal_uInt8*)pStream;
844cdf0e10cSrcweir nOutBytes = (sal_uInt32)nBytes;
845cdf0e10cSrcweir }
846cdf0e10cSrcweir
847cdf0e10cSrcweir if( nOutBytes )
848cdf0e10cSrcweir {
849cdf0e10cSrcweir // clone this object
850cdf0e10cSrcweir PDFObject* pClone = static_cast<PDFObject*>(clone());
851cdf0e10cSrcweir // set length in the dictionary to new stream length
852cdf0e10cSrcweir PDFNumber* pNewLen = new PDFNumber( double(nOutBytes) );
853cdf0e10cSrcweir pClone->m_pStream->m_pDict->insertValue( "Length", pNewLen );
854cdf0e10cSrcweir
855cdf0e10cSrcweir if( bDeflate && rWriteContext.m_bDeflate )
856cdf0e10cSrcweir {
857cdf0e10cSrcweir // delete flatedecode filter
858cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
859cdf0e10cSrcweir pClone->m_pStream->m_pDict->m_aMap.find( "Filter" );
860cdf0e10cSrcweir if( it != pClone->m_pStream->m_pDict->m_aMap.end() )
861cdf0e10cSrcweir {
862cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
863cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
864cdf0e10cSrcweir pClone->m_pStream->m_pDict->eraseValue( "Filter" );
865cdf0e10cSrcweir else
866cdf0e10cSrcweir {
867cdf0e10cSrcweir PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
868cdf0e10cSrcweir if( pArray && ! pArray->m_aSubElements.empty() )
869cdf0e10cSrcweir {
870cdf0e10cSrcweir pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
871cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir delete pFilter;
874cdf0e10cSrcweir pArray->m_aSubElements.erase( pArray->m_aSubElements.begin() );
875cdf0e10cSrcweir }
876cdf0e10cSrcweir }
877cdf0e10cSrcweir }
878cdf0e10cSrcweir }
879cdf0e10cSrcweir }
880cdf0e10cSrcweir
881cdf0e10cSrcweir // write sub elements except stream
882cdf0e10cSrcweir bool bRet = true;
883cdf0e10cSrcweir unsigned int nEle = pClone->m_aSubElements.size();
884cdf0e10cSrcweir for( unsigned int i = 0; i < nEle && bRet; i++ )
885cdf0e10cSrcweir {
886cdf0e10cSrcweir if( pClone->m_aSubElements[i] != pClone->m_pStream )
887cdf0e10cSrcweir bRet = pClone->m_aSubElements[i]->emit( rWriteContext );
888cdf0e10cSrcweir }
889cdf0e10cSrcweir delete pClone;
890cdf0e10cSrcweir // write stream
891cdf0e10cSrcweir if( bRet )
892cdf0e10cSrcweir rWriteContext.write( "stream\n", 7 );
893cdf0e10cSrcweir if( bRet )
894cdf0e10cSrcweir bRet = rWriteContext.write( pOutBytes, nOutBytes );
895cdf0e10cSrcweir if( bRet )
896cdf0e10cSrcweir bRet = rWriteContext.write( "\nendstream\nendobj\n", 18 );
897cdf0e10cSrcweir rtl_freeMemory( pStream );
898cdf0e10cSrcweir if( pOutBytes != (sal_uInt8*)pStream )
899cdf0e10cSrcweir rtl_freeMemory( pOutBytes );
900cdf0e10cSrcweir if( pEData )
901cdf0e10cSrcweir pEData->setDecryptObject( 0, 0 );
902cdf0e10cSrcweir return bRet;
903cdf0e10cSrcweir }
904cdf0e10cSrcweir if( pOutBytes != (sal_uInt8*)pStream )
905cdf0e10cSrcweir rtl_freeMemory( pOutBytes );
906cdf0e10cSrcweir }
907cdf0e10cSrcweir rtl_freeMemory( pStream );
908cdf0e10cSrcweir }
909cdf0e10cSrcweir
910cdf0e10cSrcweir bool bRet = emitSubElements( rWriteContext ) &&
911cdf0e10cSrcweir rWriteContext.write( "\nendobj\n", 8 );
912cdf0e10cSrcweir if( pEData )
913cdf0e10cSrcweir pEData->setDecryptObject( 0, 0 );
914cdf0e10cSrcweir return bRet;
915cdf0e10cSrcweir }
916cdf0e10cSrcweir
clone() const917cdf0e10cSrcweir PDFEntry* PDFObject::clone() const
918cdf0e10cSrcweir {
919cdf0e10cSrcweir PDFObject* pNewOb = new PDFObject( m_nNumber, m_nGeneration );
920cdf0e10cSrcweir cloneSubElements( pNewOb->m_aSubElements );
921cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size();
922cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir if( m_aSubElements[i] == m_pObject )
925cdf0e10cSrcweir pNewOb->m_pObject = pNewOb->m_aSubElements[i];
926cdf0e10cSrcweir else if( m_aSubElements[i] == m_pStream && pNewOb->m_pObject )
927cdf0e10cSrcweir {
928cdf0e10cSrcweir pNewOb->m_pStream = dynamic_cast<PDFStream*>(pNewOb->m_aSubElements[i]);
929cdf0e10cSrcweir PDFDict* pNewDict = dynamic_cast<PDFDict*>(pNewOb->m_pObject);
930cdf0e10cSrcweir if( pNewDict )
931cdf0e10cSrcweir pNewOb->m_pStream->m_pDict = pNewDict;
932cdf0e10cSrcweir }
933cdf0e10cSrcweir }
934cdf0e10cSrcweir return pNewOb;
935cdf0e10cSrcweir }
936cdf0e10cSrcweir
~PDFTrailer()937cdf0e10cSrcweir PDFTrailer::~PDFTrailer()
938cdf0e10cSrcweir {
939cdf0e10cSrcweir }
940cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const941cdf0e10cSrcweir bool PDFTrailer::emit( EmitContext& rWriteContext ) const
942cdf0e10cSrcweir {
943cdf0e10cSrcweir // get xref offset
944cdf0e10cSrcweir unsigned int nXRefPos = rWriteContext.getCurPos();
945cdf0e10cSrcweir // begin xref section, object 0 is always free
946cdf0e10cSrcweir if( ! rWriteContext.write( "xref\r\n"
947cdf0e10cSrcweir "0 1\r\n"
948cdf0e10cSrcweir "0000000000 65535 f\r\n", 31 ) )
949cdf0e10cSrcweir return false;
950cdf0e10cSrcweir // check if we are emitting a complete PDF file
951cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext );
952cdf0e10cSrcweir if( pEData )
953cdf0e10cSrcweir {
954cdf0e10cSrcweir // emit object xrefs
955cdf0e10cSrcweir const EmitImplData::XRefTable& rXRefs = pEData->m_aXRefTable;
956cdf0e10cSrcweir EmitImplData::XRefTable::const_iterator section_begin, section_end;
957cdf0e10cSrcweir section_begin = rXRefs.begin();
958cdf0e10cSrcweir while( section_begin != rXRefs.end() )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir // find end of continuous object numbers
961cdf0e10cSrcweir section_end = section_begin;
962cdf0e10cSrcweir unsigned int nLast = section_begin->first;
963cdf0e10cSrcweir while( (++section_end) != rXRefs.end() &&
964cdf0e10cSrcweir section_end->first == nLast+1 )
965cdf0e10cSrcweir nLast = section_end->first;
966cdf0e10cSrcweir // write first object number and number of following entries
967cdf0e10cSrcweir OStringBuffer aBuf( 21 );
968cdf0e10cSrcweir aBuf.append( sal_Int32( section_begin->first ) );
969cdf0e10cSrcweir aBuf.append( ' ' );
970cdf0e10cSrcweir aBuf.append( sal_Int32(nLast - section_begin->first + 1) );
971cdf0e10cSrcweir aBuf.append( "\r\n" );
972cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
973cdf0e10cSrcweir return false;
974cdf0e10cSrcweir while( section_begin != section_end )
975cdf0e10cSrcweir {
976cdf0e10cSrcweir // write 20 char entry of form
977cdf0e10cSrcweir // 0000offset 00gen n\r\n
978cdf0e10cSrcweir aBuf.setLength( 0 );
979cdf0e10cSrcweir OString aOffset( OString::valueOf( sal_Int64(section_begin->second.second ) ) );
980cdf0e10cSrcweir int nPad = 10 - aOffset.getLength();
981cdf0e10cSrcweir for( int i = 0; i < nPad; i++ )
982cdf0e10cSrcweir aBuf.append( '0' );
983cdf0e10cSrcweir aBuf.append( aOffset );
984cdf0e10cSrcweir aBuf.append( ' ' );
985cdf0e10cSrcweir OString aGeneration( OString::valueOf( sal_Int32(section_begin->second.first ) ) );
986cdf0e10cSrcweir nPad = 5 - aGeneration.getLength();
987cdf0e10cSrcweir for( int i = 0; i < nPad; i++ )
988cdf0e10cSrcweir aBuf.append( '0' );
989cdf0e10cSrcweir aBuf.append( aGeneration );
990cdf0e10cSrcweir aBuf.append( " n\r\n" );
991cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), 20 ) )
992cdf0e10cSrcweir return false;
993cdf0e10cSrcweir ++section_begin;
994cdf0e10cSrcweir }
995cdf0e10cSrcweir }
996cdf0e10cSrcweir }
997cdf0e10cSrcweir if( ! rWriteContext.write( "trailer\n", 8 ) )
998cdf0e10cSrcweir return false;
999cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) )
1000cdf0e10cSrcweir return false;
1001cdf0e10cSrcweir if( ! rWriteContext.write( "startxref\n", 10 ) )
1002cdf0e10cSrcweir return false;
1003cdf0e10cSrcweir rtl::OString aOffset( rtl::OString::valueOf( sal_Int32(nXRefPos) ) );
1004cdf0e10cSrcweir if( ! rWriteContext.write( aOffset.getStr(), aOffset.getLength() ) )
1005cdf0e10cSrcweir return false;
1006cdf0e10cSrcweir return rWriteContext.write( "\n%%EOF\n", 7 );
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir
clone() const1009cdf0e10cSrcweir PDFEntry* PDFTrailer::clone() const
1010cdf0e10cSrcweir {
1011cdf0e10cSrcweir PDFTrailer* pNewTr = new PDFTrailer();
1012cdf0e10cSrcweir cloneSubElements( pNewTr->m_aSubElements );
1013cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size();
1014cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ )
1015cdf0e10cSrcweir {
1016cdf0e10cSrcweir if( m_aSubElements[i] == m_pDict )
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir pNewTr->m_pDict = dynamic_cast<PDFDict*>(pNewTr->m_aSubElements[i]);
1019cdf0e10cSrcweir break;
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir }
1022cdf0e10cSrcweir return pNewTr;
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir
1025cdf0e10cSrcweir #define ENCRYPTION_KEY_LEN 16
1026cdf0e10cSrcweir #define ENCRYPTION_BUF_LEN 32
1027cdf0e10cSrcweir
1028cdf0e10cSrcweir namespace pdfparse {
1029cdf0e10cSrcweir struct PDFFileImplData
1030cdf0e10cSrcweir {
1031cdf0e10cSrcweir bool m_bIsEncrypted;
1032cdf0e10cSrcweir bool m_bStandardHandler;
1033cdf0e10cSrcweir sal_uInt32 m_nAlgoVersion;
1034cdf0e10cSrcweir sal_uInt32 m_nStandardRevision;
1035cdf0e10cSrcweir sal_uInt32 m_nKeyLength;
1036cdf0e10cSrcweir sal_uInt8 m_aOEntry[32];
1037cdf0e10cSrcweir sal_uInt8 m_aUEntry[32];
1038cdf0e10cSrcweir sal_uInt32 m_nPEntry;
1039cdf0e10cSrcweir OString m_aDocID;
1040cdf0e10cSrcweir rtlCipher m_aCipher;
1041cdf0e10cSrcweir rtlDigest m_aDigest;
1042cdf0e10cSrcweir
1043cdf0e10cSrcweir sal_uInt8 m_aDecryptionKey[ENCRYPTION_KEY_LEN+5]; // maximum handled key length
1044cdf0e10cSrcweir
PDFFileImplDatapdfparse::PDFFileImplData1045cdf0e10cSrcweir PDFFileImplData() :
1046cdf0e10cSrcweir m_bIsEncrypted( false ),
1047cdf0e10cSrcweir m_bStandardHandler( false ),
1048cdf0e10cSrcweir m_nAlgoVersion( 0 ),
1049cdf0e10cSrcweir m_nStandardRevision( 0 ),
1050cdf0e10cSrcweir m_nKeyLength( 0 ),
1051cdf0e10cSrcweir m_nPEntry( 0 ),
1052cdf0e10cSrcweir m_aCipher( NULL ),
1053cdf0e10cSrcweir m_aDigest( NULL )
1054cdf0e10cSrcweir {
1055cdf0e10cSrcweir rtl_zeroMemory( m_aOEntry, sizeof( m_aOEntry ) );
1056cdf0e10cSrcweir rtl_zeroMemory( m_aUEntry, sizeof( m_aUEntry ) );
1057cdf0e10cSrcweir rtl_zeroMemory( m_aDecryptionKey, sizeof( m_aDecryptionKey ) );
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir
~PDFFileImplDatapdfparse::PDFFileImplData1060cdf0e10cSrcweir ~PDFFileImplData()
1061cdf0e10cSrcweir {
1062cdf0e10cSrcweir if( m_aCipher )
1063cdf0e10cSrcweir rtl_cipher_destroyARCFOUR( m_aCipher );
1064cdf0e10cSrcweir if( m_aDigest )
1065cdf0e10cSrcweir rtl_digest_destroyMD5( m_aDigest );
1066cdf0e10cSrcweir }
1067cdf0e10cSrcweir };
1068cdf0e10cSrcweir }
1069cdf0e10cSrcweir
~PDFFile()1070cdf0e10cSrcweir PDFFile::~PDFFile()
1071cdf0e10cSrcweir {
1072cdf0e10cSrcweir if( m_pData )
1073cdf0e10cSrcweir delete m_pData;
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir
isEncrypted() const1076cdf0e10cSrcweir bool PDFFile::isEncrypted() const
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir return impl_getData()->m_bIsEncrypted;
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir
decrypt(const sal_uInt8 * pInBuffer,sal_uInt32 nLen,sal_uInt8 * pOutBuffer,unsigned int nObject,unsigned int nGeneration) const1081cdf0e10cSrcweir bool PDFFile::decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
1082cdf0e10cSrcweir unsigned int nObject, unsigned int nGeneration ) const
1083cdf0e10cSrcweir {
1084cdf0e10cSrcweir if( ! isEncrypted() )
1085cdf0e10cSrcweir return false;
1086cdf0e10cSrcweir
1087cdf0e10cSrcweir if( ! m_pData->m_aCipher )
1088cdf0e10cSrcweir m_pData->m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
1089cdf0e10cSrcweir
1090cdf0e10cSrcweir // modify encryption key
1091cdf0e10cSrcweir sal_uInt32 i = m_pData->m_nKeyLength;
1092cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8(nObject&0xff);
1093cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>8)&0xff);
1094cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>16)&0xff);
1095cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8(nGeneration&0xff);
1096cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nGeneration>>8)&0xff);
1097cdf0e10cSrcweir
1098cdf0e10cSrcweir sal_uInt8 aSum[ENCRYPTION_KEY_LEN];
1099cdf0e10cSrcweir rtl_digest_updateMD5( m_pData->m_aDigest, m_pData->m_aDecryptionKey, i );
1100cdf0e10cSrcweir rtl_digest_getMD5( m_pData->m_aDigest, aSum, sizeof( aSum ) );
1101cdf0e10cSrcweir
1102cdf0e10cSrcweir if( i > 16 )
1103cdf0e10cSrcweir i = 16;
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir rtlCipherError aErr = rtl_cipher_initARCFOUR( m_pData->m_aCipher,
1106cdf0e10cSrcweir rtl_Cipher_DirectionDecode,
1107cdf0e10cSrcweir aSum, i,
1108cdf0e10cSrcweir NULL, 0 );
1109cdf0e10cSrcweir if( aErr == rtl_Cipher_E_None )
1110cdf0e10cSrcweir aErr = rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1111cdf0e10cSrcweir pInBuffer, nLen,
1112cdf0e10cSrcweir pOutBuffer, nLen );
1113cdf0e10cSrcweir return aErr == rtl_Cipher_E_None;
1114cdf0e10cSrcweir }
1115cdf0e10cSrcweir
1116cdf0e10cSrcweir static const sal_uInt8 nPadString[32] =
1117cdf0e10cSrcweir {
1118cdf0e10cSrcweir 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
1119cdf0e10cSrcweir 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
1120cdf0e10cSrcweir };
1121cdf0e10cSrcweir
pad_or_truncate_to_32(const OString & rStr,sal_Char * pBuffer)1122cdf0e10cSrcweir static void pad_or_truncate_to_32( const OString& rStr, sal_Char* pBuffer )
1123cdf0e10cSrcweir {
1124cdf0e10cSrcweir int nLen = rStr.getLength();
1125cdf0e10cSrcweir if( nLen > 32 )
1126cdf0e10cSrcweir nLen = 32;
1127cdf0e10cSrcweir const sal_Char* pStr = rStr.getStr();
1128cdf0e10cSrcweir rtl_copyMemory( pBuffer, pStr, nLen );
1129cdf0e10cSrcweir int i = 0;
1130cdf0e10cSrcweir while( nLen < 32 )
1131cdf0e10cSrcweir pBuffer[nLen++] = nPadString[i++];
1132cdf0e10cSrcweir }
1133cdf0e10cSrcweir
1134cdf0e10cSrcweir // pass at least pData->m_nKeyLength bytes in
password_to_key(const OString & rPwd,sal_uInt8 * pOutKey,PDFFileImplData * pData,bool bComputeO)1135cdf0e10cSrcweir static sal_uInt32 password_to_key( const OString& rPwd, sal_uInt8* pOutKey, PDFFileImplData* pData, bool bComputeO )
1136cdf0e10cSrcweir {
1137cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.2
1138cdf0e10cSrcweir // encrypt pad string
1139cdf0e10cSrcweir sal_Char aPadPwd[ENCRYPTION_BUF_LEN];
1140cdf0e10cSrcweir pad_or_truncate_to_32( rPwd, aPadPwd );
1141cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, aPadPwd, sizeof( aPadPwd ) );
1142cdf0e10cSrcweir if( ! bComputeO )
1143cdf0e10cSrcweir {
1144cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aOEntry, 32 );
1145cdf0e10cSrcweir sal_uInt8 aPEntry[4];
1146cdf0e10cSrcweir aPEntry[0] = static_cast<sal_uInt8>(pData->m_nPEntry & 0xff);
1147cdf0e10cSrcweir aPEntry[1] = static_cast<sal_uInt8>((pData->m_nPEntry >> 8 ) & 0xff);
1148cdf0e10cSrcweir aPEntry[2] = static_cast<sal_uInt8>((pData->m_nPEntry >> 16) & 0xff);
1149cdf0e10cSrcweir aPEntry[3] = static_cast<sal_uInt8>((pData->m_nPEntry >> 24) & 0xff);
1150cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, aPEntry, sizeof(aPEntry) );
1151cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir sal_uInt8 nSum[RTL_DIGEST_LENGTH_MD5];
1154cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1155cdf0e10cSrcweir if( pData->m_nStandardRevision == 3 )
1156cdf0e10cSrcweir {
1157cdf0e10cSrcweir for( int i = 0; i < 50; i++ )
1158cdf0e10cSrcweir {
1159cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1160cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) );
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir }
1163cdf0e10cSrcweir sal_uInt32 nLen = pData->m_nKeyLength;
1164cdf0e10cSrcweir if( nLen > RTL_DIGEST_LENGTH_MD5 )
1165cdf0e10cSrcweir nLen = RTL_DIGEST_LENGTH_MD5;
1166cdf0e10cSrcweir rtl_copyMemory( pOutKey, nSum, nLen );
1167cdf0e10cSrcweir return nLen;
1168cdf0e10cSrcweir }
1169cdf0e10cSrcweir
check_user_password(const OString & rPwd,PDFFileImplData * pData)1170cdf0e10cSrcweir static bool check_user_password( const OString& rPwd, PDFFileImplData* pData )
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.6
1173cdf0e10cSrcweir bool bValid = false;
1174cdf0e10cSrcweir sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
1175cdf0e10cSrcweir sal_uInt8 nEncryptedEntry[ENCRYPTION_BUF_LEN];
1176cdf0e10cSrcweir rtl_zeroMemory( nEncryptedEntry, sizeof(nEncryptedEntry) );
1177cdf0e10cSrcweir sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, pData, false );
1178cdf0e10cSrcweir // save (at this time potential) decryption key for later use
1179cdf0e10cSrcweir rtl_copyMemory( pData->m_aDecryptionKey, aKey, nKeyLen );
1180cdf0e10cSrcweir if( pData->m_nStandardRevision == 2 )
1181cdf0e10cSrcweir {
1182cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.4
1183cdf0e10cSrcweir // encrypt pad string
1184cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1185cdf0e10cSrcweir aKey, nKeyLen,
1186cdf0e10cSrcweir NULL, 0 );
1187cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher, nPadString, sizeof( nPadString ),
1188cdf0e10cSrcweir nEncryptedEntry, sizeof( nEncryptedEntry ) );
1189cdf0e10cSrcweir bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 32 ) == 0);
1190cdf0e10cSrcweir }
1191cdf0e10cSrcweir else if( pData->m_nStandardRevision == 3 )
1192cdf0e10cSrcweir {
1193cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.5
1194cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, nPadString, sizeof( nPadString ) );
1195cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() );
1196cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nEncryptedEntry, sizeof(nEncryptedEntry) );
1197cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1198cdf0e10cSrcweir aKey, sizeof(aKey), NULL, 0 );
1199cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher,
1200cdf0e10cSrcweir nEncryptedEntry, 16,
1201cdf0e10cSrcweir nEncryptedEntry, 16 ); // encrypt in place
1202cdf0e10cSrcweir for( int i = 1; i <= 19; i++ ) // do it 19 times, start with 1
1203cdf0e10cSrcweir {
1204cdf0e10cSrcweir sal_uInt8 aTempKey[ENCRYPTION_KEY_LEN];
1205cdf0e10cSrcweir for( sal_uInt32 j = 0; j < sizeof(aTempKey); j++ )
1206cdf0e10cSrcweir aTempKey[j] = static_cast<sal_uInt8>( aKey[j] ^ i );
1207cdf0e10cSrcweir
1208cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode,
1209cdf0e10cSrcweir aTempKey, sizeof(aTempKey), NULL, 0 );
1210cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher,
1211cdf0e10cSrcweir nEncryptedEntry, 16,
1212cdf0e10cSrcweir nEncryptedEntry, 16 ); // encrypt in place
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 16 ) == 0);
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir return bValid;
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir
setupDecryptionData(const OString & rPwd) const1219cdf0e10cSrcweir bool PDFFile::setupDecryptionData( const OString& rPwd ) const
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir if( !impl_getData()->m_bIsEncrypted )
1222cdf0e10cSrcweir return rPwd.getLength() == 0;
1223cdf0e10cSrcweir
1224cdf0e10cSrcweir // check if we can handle this encryption at all
1225cdf0e10cSrcweir if( ! m_pData->m_bStandardHandler ||
1226cdf0e10cSrcweir m_pData->m_nAlgoVersion < 1 ||
1227cdf0e10cSrcweir m_pData->m_nAlgoVersion > 2 ||
1228cdf0e10cSrcweir m_pData->m_nStandardRevision < 2 ||
1229cdf0e10cSrcweir m_pData->m_nStandardRevision > 3 )
1230cdf0e10cSrcweir return false;
1231cdf0e10cSrcweir
1232cdf0e10cSrcweir if( ! m_pData->m_aCipher )
1233cdf0e10cSrcweir m_pData->m_aCipher = rtl_cipher_createARCFOUR(rtl_Cipher_ModeStream);
1234cdf0e10cSrcweir if( ! m_pData->m_aDigest )
1235cdf0e10cSrcweir m_pData->m_aDigest = rtl_digest_createMD5();
1236cdf0e10cSrcweir
1237cdf0e10cSrcweir // first try user password
1238cdf0e10cSrcweir bool bValid = check_user_password( rPwd, m_pData );
1239cdf0e10cSrcweir
1240cdf0e10cSrcweir if( ! bValid )
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir // try owner password
1243cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.7
1244cdf0e10cSrcweir sal_uInt8 aKey[ENCRYPTION_KEY_LEN];
1245cdf0e10cSrcweir sal_uInt8 nPwd[ENCRYPTION_BUF_LEN];
1246cdf0e10cSrcweir rtl_zeroMemory( nPwd, sizeof(nPwd) );
1247cdf0e10cSrcweir sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, m_pData, true );
1248cdf0e10cSrcweir if( m_pData->m_nStandardRevision == 2 )
1249cdf0e10cSrcweir {
1250cdf0e10cSrcweir rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
1251cdf0e10cSrcweir aKey, nKeyLen, NULL, 0 );
1252cdf0e10cSrcweir rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1253cdf0e10cSrcweir m_pData->m_aOEntry, 32,
1254cdf0e10cSrcweir nPwd, 32 );
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir else if( m_pData->m_nStandardRevision == 3 )
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir rtl_copyMemory( nPwd, m_pData->m_aOEntry, 32 );
1259cdf0e10cSrcweir for( int i = 19; i >= 0; i-- )
1260cdf0e10cSrcweir {
1261cdf0e10cSrcweir sal_uInt8 nTempKey[ENCRYPTION_KEY_LEN];
1262cdf0e10cSrcweir for( unsigned int j = 0; j < sizeof(nTempKey); j++ )
1263cdf0e10cSrcweir nTempKey[j] = sal_uInt8(aKey[j] ^ i);
1264cdf0e10cSrcweir rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode,
1265cdf0e10cSrcweir nTempKey, nKeyLen, NULL, 0 );
1266cdf0e10cSrcweir rtl_cipher_decodeARCFOUR( m_pData->m_aCipher,
1267cdf0e10cSrcweir nPwd, 32,
1268cdf0e10cSrcweir nPwd, 32 ); // decrypt inplace
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir bValid = check_user_password( OString( (sal_Char*)nPwd, 32 ), m_pData );
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir
1274cdf0e10cSrcweir return bValid;
1275cdf0e10cSrcweir }
1276cdf0e10cSrcweir
getDecryptionKey() const1277cdf0e10cSrcweir rtl::OUString PDFFile::getDecryptionKey() const
1278cdf0e10cSrcweir {
1279cdf0e10cSrcweir rtl::OUStringBuffer aBuf( ENCRYPTION_KEY_LEN * 2 );
1280cdf0e10cSrcweir if( impl_getData()->m_bIsEncrypted )
1281cdf0e10cSrcweir {
1282cdf0e10cSrcweir for( sal_uInt32 i = 0; i < m_pData->m_nKeyLength; i++ )
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir static const sal_Unicode pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
1285cdf0e10cSrcweir '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1286cdf0e10cSrcweir aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] >> 4) & 0x0f] );
1287cdf0e10cSrcweir aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] & 0x0f)] );
1288cdf0e10cSrcweir }
1289cdf0e10cSrcweir
1290cdf0e10cSrcweir }
1291cdf0e10cSrcweir return aBuf.makeStringAndClear();
1292cdf0e10cSrcweir }
1293cdf0e10cSrcweir
impl_getData() const1294cdf0e10cSrcweir PDFFileImplData* PDFFile::impl_getData() const
1295cdf0e10cSrcweir {
1296cdf0e10cSrcweir if( m_pData )
1297cdf0e10cSrcweir return m_pData;
1298cdf0e10cSrcweir m_pData = new PDFFileImplData();
1299cdf0e10cSrcweir // check for encryption dict in a trailer
1300cdf0e10cSrcweir unsigned int nElements = m_aSubElements.size();
1301cdf0e10cSrcweir while( nElements-- > 0 )
1302cdf0e10cSrcweir {
1303cdf0e10cSrcweir PDFTrailer* pTrailer = dynamic_cast<PDFTrailer*>(m_aSubElements[nElements]);
1304cdf0e10cSrcweir if( pTrailer && pTrailer->m_pDict )
1305cdf0e10cSrcweir {
1306cdf0e10cSrcweir // search doc id
1307cdf0e10cSrcweir PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID" );
1308cdf0e10cSrcweir if( doc_id != pTrailer->m_pDict->m_aMap.end() )
1309cdf0e10cSrcweir {
1310cdf0e10cSrcweir PDFArray* pArr = dynamic_cast<PDFArray*>(doc_id->second);
1311cdf0e10cSrcweir if( pArr && pArr->m_aSubElements.size() > 0 )
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir PDFString* pStr = dynamic_cast<PDFString*>(pArr->m_aSubElements[0]);
1314cdf0e10cSrcweir if( pStr )
1315cdf0e10cSrcweir m_pData->m_aDocID = pStr->getFilteredString();
1316cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1317cdf0e10cSrcweir fprintf( stderr, "DocId is <" );
1318cdf0e10cSrcweir for( int i = 0; i < m_pData->m_aDocID.getLength(); i++ )
1319cdf0e10cSrcweir fprintf( stderr, "%.2x", (unsigned int)sal_uInt8(m_pData->m_aDocID.getStr()[i]) );
1320cdf0e10cSrcweir fprintf( stderr, ">\n" );
1321cdf0e10cSrcweir #endif
1322cdf0e10cSrcweir }
1323cdf0e10cSrcweir }
1324cdf0e10cSrcweir // search Encrypt entry
1325cdf0e10cSrcweir PDFDict::Map::iterator enc =
1326cdf0e10cSrcweir pTrailer->m_pDict->m_aMap.find( "Encrypt" );
1327cdf0e10cSrcweir if( enc != pTrailer->m_pDict->m_aMap.end() )
1328cdf0e10cSrcweir {
1329cdf0e10cSrcweir PDFDict* pDict = dynamic_cast<PDFDict*>(enc->second);
1330cdf0e10cSrcweir if( ! pDict )
1331cdf0e10cSrcweir {
1332cdf0e10cSrcweir PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(enc->second);
1333cdf0e10cSrcweir if( pRef )
1334cdf0e10cSrcweir {
1335cdf0e10cSrcweir PDFObject* pObj = findObject( pRef );
1336cdf0e10cSrcweir if( pObj && pObj->m_pObject )
1337cdf0e10cSrcweir pDict = dynamic_cast<PDFDict*>(pObj->m_pObject);
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir }
1340cdf0e10cSrcweir if( pDict )
1341cdf0e10cSrcweir {
1342cdf0e10cSrcweir PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter" );
1343cdf0e10cSrcweir PDFDict::Map::iterator version = pDict->m_aMap.find( "V" );
1344cdf0e10cSrcweir PDFDict::Map::iterator len = pDict->m_aMap.find( "Length" );
1345cdf0e10cSrcweir PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O" );
1346cdf0e10cSrcweir PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U" );
1347cdf0e10cSrcweir PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R" );
1348cdf0e10cSrcweir PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P" );
1349cdf0e10cSrcweir if( filter != pDict->m_aMap.end() )
1350cdf0e10cSrcweir {
1351cdf0e10cSrcweir m_pData->m_bIsEncrypted = true;
1352cdf0e10cSrcweir m_pData->m_nKeyLength = 5;
1353cdf0e10cSrcweir if( version != pDict->m_aMap.end() )
1354cdf0e10cSrcweir {
1355cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(version->second);
1356cdf0e10cSrcweir if( pNum )
1357cdf0e10cSrcweir m_pData->m_nAlgoVersion = static_cast<sal_uInt32>(pNum->m_fValue);
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir if( m_pData->m_nAlgoVersion >= 3 )
1360cdf0e10cSrcweir m_pData->m_nKeyLength = 16;
1361cdf0e10cSrcweir if( len != pDict->m_aMap.end() )
1362cdf0e10cSrcweir {
1363cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(len->second);
1364cdf0e10cSrcweir if( pNum )
1365cdf0e10cSrcweir m_pData->m_nKeyLength = static_cast<sal_uInt32>(pNum->m_fValue) / 8;
1366cdf0e10cSrcweir }
1367cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(filter->second);
1368cdf0e10cSrcweir if( pFilter && pFilter->getFilteredName().equalsAscii( "Standard" ) )
1369cdf0e10cSrcweir m_pData->m_bStandardHandler = true;
1370cdf0e10cSrcweir if( o_ent != pDict->m_aMap.end() )
1371cdf0e10cSrcweir {
1372cdf0e10cSrcweir PDFString* pString = dynamic_cast<PDFString*>(o_ent->second);
1373cdf0e10cSrcweir if( pString )
1374cdf0e10cSrcweir {
1375cdf0e10cSrcweir OString aEnt = pString->getFilteredString();
1376cdf0e10cSrcweir if( aEnt.getLength() == 32 )
1377cdf0e10cSrcweir rtl_copyMemory( m_pData->m_aOEntry, aEnt.getStr(), 32 );
1378cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1379cdf0e10cSrcweir else
1380cdf0e10cSrcweir {
1381cdf0e10cSrcweir fprintf( stderr, "O entry has length %d, should be 32 <", (int)aEnt.getLength() );
1382cdf0e10cSrcweir for( int i = 0; i < aEnt.getLength(); i++ )
1383cdf0e10cSrcweir fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
1384cdf0e10cSrcweir fprintf( stderr, ">\n" );
1385cdf0e10cSrcweir }
1386cdf0e10cSrcweir #endif
1387cdf0e10cSrcweir }
1388cdf0e10cSrcweir }
1389cdf0e10cSrcweir if( u_ent != pDict->m_aMap.end() )
1390cdf0e10cSrcweir {
1391cdf0e10cSrcweir PDFString* pString = dynamic_cast<PDFString*>(u_ent->second);
1392cdf0e10cSrcweir if( pString )
1393cdf0e10cSrcweir {
1394cdf0e10cSrcweir OString aEnt = pString->getFilteredString();
1395cdf0e10cSrcweir if( aEnt.getLength() == 32 )
1396cdf0e10cSrcweir rtl_copyMemory( m_pData->m_aUEntry, aEnt.getStr(), 32 );
1397cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1398cdf0e10cSrcweir else
1399cdf0e10cSrcweir {
1400cdf0e10cSrcweir fprintf( stderr, "U entry has length %d, should be 32 <", (int)aEnt.getLength() );
1401cdf0e10cSrcweir for( int i = 0; i < aEnt.getLength(); i++ )
1402cdf0e10cSrcweir fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) );
1403cdf0e10cSrcweir fprintf( stderr, ">\n" );
1404cdf0e10cSrcweir }
1405cdf0e10cSrcweir #endif
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir if( r_ent != pDict->m_aMap.end() )
1409cdf0e10cSrcweir {
1410cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(r_ent->second);
1411cdf0e10cSrcweir if( pNum )
1412cdf0e10cSrcweir m_pData->m_nStandardRevision = static_cast<sal_uInt32>(pNum->m_fValue);
1413cdf0e10cSrcweir }
1414cdf0e10cSrcweir if( p_ent != pDict->m_aMap.end() )
1415cdf0e10cSrcweir {
1416cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(p_ent->second);
1417cdf0e10cSrcweir if( pNum )
1418cdf0e10cSrcweir m_pData->m_nPEntry = static_cast<sal_uInt32>(static_cast<sal_Int32>(pNum->m_fValue));
1419cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1420cdf0e10cSrcweir fprintf( stderr, "p entry is %p\n", (void*)m_pData->m_nPEntry );
1421cdf0e10cSrcweir #endif
1422cdf0e10cSrcweir }
1423cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
1424cdf0e10cSrcweir fprintf( stderr, "Encryption dict: sec handler: %s, version = %d, revision = %d, key length = %d\n",
1425cdf0e10cSrcweir pFilter ? OUStringToOString( pFilter->getFilteredName(), RTL_TEXTENCODING_UTF8 ).getStr() : "<unknown>",
1426cdf0e10cSrcweir (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, (int)m_pData->m_nKeyLength );
1427cdf0e10cSrcweir #endif
1428cdf0e10cSrcweir break;
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir }
1431cdf0e10cSrcweir }
1432cdf0e10cSrcweir }
1433cdf0e10cSrcweir }
1434cdf0e10cSrcweir
1435cdf0e10cSrcweir return m_pData;
1436cdf0e10cSrcweir }
1437cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const1438cdf0e10cSrcweir bool PDFFile::emit( EmitContext& rWriteContext ) const
1439cdf0e10cSrcweir {
1440cdf0e10cSrcweir setEmitData( rWriteContext, new EmitImplData( this ) );
1441cdf0e10cSrcweir
1442cdf0e10cSrcweir OStringBuffer aBuf( 32 );
1443cdf0e10cSrcweir aBuf.append( "%PDF-" );
1444cdf0e10cSrcweir aBuf.append( sal_Int32( m_nMajor ) );
1445cdf0e10cSrcweir aBuf.append( '.' );
1446cdf0e10cSrcweir aBuf.append( sal_Int32( m_nMinor ) );
1447cdf0e10cSrcweir aBuf.append( "\n" );
1448cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
1449cdf0e10cSrcweir return false;
1450cdf0e10cSrcweir return emitSubElements( rWriteContext );
1451cdf0e10cSrcweir }
1452cdf0e10cSrcweir
clone() const1453cdf0e10cSrcweir PDFEntry* PDFFile::clone() const
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir PDFFile* pNewFl = new PDFFile();
1456cdf0e10cSrcweir pNewFl->m_nMajor = m_nMajor;
1457cdf0e10cSrcweir pNewFl->m_nMinor = m_nMinor;
1458cdf0e10cSrcweir cloneSubElements( pNewFl->m_aSubElements );
1459cdf0e10cSrcweir return pNewFl;
1460cdf0e10cSrcweir }
1461cdf0e10cSrcweir
~PDFPart()1462cdf0e10cSrcweir PDFPart::~PDFPart()
1463cdf0e10cSrcweir {
1464cdf0e10cSrcweir }
1465cdf0e10cSrcweir
emit(EmitContext & rWriteContext) const1466cdf0e10cSrcweir bool PDFPart::emit( EmitContext& rWriteContext ) const
1467cdf0e10cSrcweir {
1468cdf0e10cSrcweir return emitSubElements( rWriteContext );
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir
clone() const1471cdf0e10cSrcweir PDFEntry* PDFPart::clone() const
1472cdf0e10cSrcweir {
1473cdf0e10cSrcweir PDFPart* pNewPt = new PDFPart();
1474cdf0e10cSrcweir cloneSubElements( pNewPt->m_aSubElements );
1475cdf0e10cSrcweir return pNewPt;
1476cdf0e10cSrcweir }
1477cdf0e10cSrcweir
1478