From: Francesco Pretto <cez...@gmail.com>
Added mechanism to automatic set PdfObject ownership, removing public access to manual setting. To perform this a PdfOwnedDataType is added and PdfArray, PdfDictionary now inherits this class, propagating ownership when objects are added to these collections: Also added methods: PdfArray::FindAt(idx) PdfDictionary::FindKey(key) PdfDictionary::FindKeyParent(key) Also in PdfObject commented out the attempt to copy the stream from objects in copy constructor and assignment operator since: 1) As of r1957 it's already broken since PdfVecObjects::CreateStream( const PdfStream & ) just returns NULL 2) Stream should be copyable also when m_pOwner is NULL --- CMakeLists.txt | 2 +- podofo/base/PdfOwnedDataType.h | 12 ++++ src/CMakeLists.txt | 2 + src/base/PdfArray.cpp | 94 ++++++++++++++++++++++++--- src/base/PdfArray.h | 114 +++++++++++++++------------------ src/base/PdfDictionary.cpp | 75 +++++++++++++++++----- src/base/PdfDictionary.h | 92 ++++++++++++++++++++++++-- src/base/PdfObject.cpp | 84 ++++++++++++++++-------- src/base/PdfObject.h | 35 +++++----- src/base/PdfOwnedDataType.cpp | 78 ++++++++++++++++++++++ src/base/PdfOwnedDataType.h | 84 ++++++++++++++++++++++++ src/base/PdfVariant.h | 15 +++++ src/doc/PdfPage.cpp | 6 +- src/doc/PdfShadingPattern.cpp | 1 - 14 files changed, 552 insertions(+), 142 deletions(-) create mode 100644 podofo/base/PdfOwnedDataType.h create mode 100644 src/base/PdfOwnedDataType.cpp create mode 100644 src/base/PdfOwnedDataType.h
diff --git a/CMakeLists.txt b/CMakeLists.txt index f23dd5a..7b88aa6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,7 +290,7 @@ IF(CMAKE_COMPILER_IS_GNUCXX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Woverloaded-virtual -Wswitch-enum -Wcast-qual -Wwrite-strings -Wredundant-decls -Wreorder -Wno-deprecated-declarations") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Woverloaded-virtual -Wswitch -Wcast-qual -Wwrite-strings -Wredundant-decls -Wreorder -Wno-deprecated-declarations") # # Note that we do not need debug definitions here. Set diff --git a/podofo/base/PdfOwnedDataType.h b/podofo/base/PdfOwnedDataType.h new file mode 100644 index 0000000..dd35fa0 --- /dev/null +++ b/podofo/base/PdfOwnedDataType.h @@ -0,0 +1,12 @@ + +#ifndef PODOFO_WRAPPER_PDFOWNEDDATATYPEH +#define PODOFO_WRAPPER_PDFOWNEDDATATYPEH +/* + * This is a simple wrapper include file that lets you include + * <podofo/base/PdfOwnedDataType.h> when building against a podofo build directory + * rather than an installed copy of podofo. You'll probably need + * this if you're including your own (probably static) copy of podofo + * using a mechanism like svn:externals . + */ +#include "../../src/base/PdfOwnedDataType.h" +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 72bbd97..bba6b5f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,7 @@ SET(PODOFO_BASE_SOURCES base/PdfContentsTokenizer.cpp base/PdfData.cpp base/PdfDataType.cpp + base/PdfOwnedDataType.cpp base/PdfDate.cpp base/PdfDictionary.cpp base/PdfEncoding.cpp @@ -124,6 +125,7 @@ SET(PODOFO_BASE_HEADERS base/PdfContentsTokenizer.h base/PdfData.h base/PdfDataType.h + base/PdfOwnedDataType.h base/PdfDate.h base/PdfDefines.h base/PdfDefinesPrivate.h diff --git a/src/base/PdfArray.cpp b/src/base/PdfArray.cpp index f44b64b..508daf9 100644 --- a/src/base/PdfArray.cpp +++ b/src/base/PdfArray.cpp @@ -41,7 +41,18 @@ namespace PoDoFo { PdfArray::PdfArray() - : PdfDataType(), m_bDirty( false ) + : m_bDirty( false ) +{ +} + +PdfArray::PdfArray( const PdfObject &var ) + : m_bDirty( false ) +{ + this->push_back( var ); +} + +PdfArray::PdfArray(const PdfArray & rhs) + : PdfOwnedDataType( rhs ), m_bDirty( rhs.m_bDirty ), m_objects( rhs.m_objects ) { } @@ -49,25 +60,60 @@ PdfArray::~PdfArray() { } -PdfArray::PdfArray( const PdfObject & var ) - : PdfDataType(), m_bDirty( false ) +PdfObject * PdfArray::findAt( size_type idx ) const +{ + PdfObject *obj = &const_cast<PdfArray *>( this )->m_objects[idx]; + if ( obj->IsReference() ) + return GetIndirectObject( obj->GetReference() ); + else + return obj; +} + +void PdfArray::clear() { - this->push_back( var ); + AssertMutable(); + if ( m_objects.size() == 0 ) + return; + + m_objects.clear(); + m_bDirty = true; +} + +PdfArray::iterator PdfArray::insert( const iterator &pos, const PdfObject &val ) +{ + AssertMutable(); + + m_bDirty = true; + iterator ret = m_objects.insert( pos, val ); + PdfVecObjects *pOwner = GetObjectOwner(); + if ( pOwner != NULL ) + ret->SetOwner( pOwner ); + return ret; } -PdfArray::PdfArray( const PdfArray & rhs ) - : PdfDataType( rhs ), m_bDirty( rhs.m_bDirty ), m_objects( rhs.m_objects ) +void PdfArray::erase( const iterator &pos ) { - this->operator=( rhs ); + AssertMutable(); + + m_objects.erase( pos ); + m_bDirty = true; } +void PdfArray::erase( const iterator &first, const iterator &last ) +{ + AssertMutable(); + + m_objects.erase( first, last ); + m_bDirty = true; +} -PdfArray& PdfArray::operator=(const PdfArray& rhs) +PdfArray& PdfArray::operator=( const PdfArray &rhs ) { if (this != &rhs) { m_bDirty = rhs.m_bDirty; m_objects = rhs.m_objects; + this->PdfOwnedDataType::operator=( rhs ); } else { @@ -77,6 +123,22 @@ PdfArray& PdfArray::operator=(const PdfArray& rhs) return *this; } +void PdfArray::resize( size_t count, value_type val ) +{ + AssertMutable(); + + size_t currentSize = size(); + m_objects.resize( count, val ); + PdfVecObjects *pOwner = GetObjectOwner(); + if ( pOwner != NULL ) + { + for ( size_t i = currentSize; i < count; i++ ) + m_objects[i].SetOwner( pOwner ); + } + + m_bDirty = currentSize != count; +} + void PdfArray::Write( PdfOutputDevice* pDevice, EPdfWriteMode eWriteMode, const PdfEncrypt* pEncrypt ) const { @@ -181,6 +243,20 @@ void PdfArray::SetDirty( bool bDirty ) ++it; } } +} + +void PdfArray::SetOwner( PdfObject *pOwner ) +{ + PdfOwnedDataType::SetOwner( pOwner ); + PdfVecObjects *pVecOwner = pOwner->GetOwner(); + if ( pVecOwner != NULL ) + { + // Set owmership for all children + PdfArray::iterator it = this->begin(); + PdfArray::iterator end = this->end(); + for ( ; it != end; it++ ) + it->SetOwner( pVecOwner ); + } } - + }; diff --git a/src/base/PdfArray.h b/src/base/PdfArray.h index ce4d177..d791c3a 100644 --- a/src/base/PdfArray.h +++ b/src/base/PdfArray.h @@ -42,7 +42,7 @@ #endif // _WIN32 #include "PdfDefines.h" -#include "PdfDataType.h" +#include "PdfOwnedDataType.h" #include "PdfObject.h" namespace PoDoFo { @@ -54,7 +54,7 @@ namespace PoDoFo { * * \see PdfVariant */ -class PODOFO_API PdfArray : public PdfDataType { +class PODOFO_API PdfArray : public PdfOwnedDataType { public: typedef size_t size_type; typedef PdfObject value_type; @@ -126,6 +126,18 @@ class PODOFO_API PdfArray : public PdfDataType { */ size_t GetStringIndex( const std::string& cmpString ) const; + /** Get the object at the given index out of the array. + * + * Lookup in the indirect objects as well, if the shallow object was a reference. + * The returned value is a pointer to the internal object in the dictionary + * so it MUST not be deleted. + * + * \param idx + * \returns pointer to the found value. NULL if the index was out of the boundaries + */ + inline const PdfObject * FindAt( size_type idx ) const; + inline PdfObject * FindAt( size_type idx ); + /** Adds a PdfObject to the array * * \param var add a PdfObject to the array @@ -137,7 +149,7 @@ class PODOFO_API PdfArray : public PdfDataType { /** Remove all elements from the array */ - inline void clear(); + void clear(); /** * \returns the size of the array @@ -154,9 +166,10 @@ class PODOFO_API PdfArray : public PdfDataType { /** * Resize the internal vector. - * \param __n new size + * \param count new size + * \param value refernce value */ - inline void resize(size_t __n, value_type __x = value_type()); + void resize( size_t count, value_type val = value_type() ); /** * Returns a read/write iterator that points to the first @@ -225,10 +238,10 @@ class PODOFO_API PdfArray : public PdfDataType { const _InputIterator& __last); #endif - inline PdfArray::iterator insert(const iterator& __position, const PdfObject & val ); + iterator insert( const iterator &pos, const PdfObject &val ); - inline void erase( const iterator& pos ); - inline void erase( const iterator& first, const iterator& last ); + void erase( const iterator& pos ); + void erase( const iterator& first, const iterator& last ); inline void reserve(size_type __n); @@ -281,19 +294,31 @@ class PODOFO_API PdfArray : public PdfDataType { */ virtual void SetDirty( bool bDirty ); + protected: + void SetOwner( PdfObject* pOwner ); + + private: + PdfObject * findAt(size_type idx) const; + private: bool m_bDirty; ///< Indicates if this object was modified after construction std::vector<PdfObject> m_objects; }; // ----------------------------------------------------- -// +// // ----------------------------------------------------- -void PdfArray::Clear() -{ - AssertMutable(); +inline const PdfObject * PdfArray::FindAt( size_type idx ) const +{ + return const_cast<PdfArray &>( *this ).FindAt( idx ); +} - m_objects.clear(); +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline PdfObject * PdfArray::FindAt( size_type idx ) +{ + return const_cast<PdfArray &>( *this ).FindAt( idx ); } // ----------------------------------------------------- @@ -301,7 +326,7 @@ void PdfArray::Clear() // ----------------------------------------------------- size_t PdfArray::GetSize() const { - return this->size(); + return m_objects.size(); } // ----------------------------------------------------- @@ -309,20 +334,15 @@ size_t PdfArray::GetSize() const // ----------------------------------------------------- void PdfArray::push_back( const PdfObject & var ) { - AssertMutable(); - - m_objects.push_back( var ); - m_bDirty = true; + insert( end(), var ); } // ----------------------------------------------------- // // ----------------------------------------------------- -void PdfArray::clear() +void PdfArray::Clear() { - AssertMutable(); - - m_objects.clear(); + clear(); } // ----------------------------------------------------- @@ -359,14 +379,6 @@ const PdfObject& PdfArray::operator[](size_type __n) const return m_objects[__n]; } -// ----------------------------------------------------- -// -// ----------------------------------------------------- -void PdfArray::resize(size_t __n, value_type __x) -{ - m_objects.resize(__n, __x); -} - // ----------------------------------------------------- // // ----------------------------------------------------- @@ -447,48 +459,26 @@ void PdfArray::insert(const PdfArray::iterator& __position, { AssertMutable(); - m_objects.insert( __position, __first, __last ); - m_bDirty = true; -} - -// ----------------------------------------------------- -// -// ----------------------------------------------------- -PdfArray::iterator PdfArray::insert(const iterator& __position, const PdfObject & val ) -{ - AssertMutable(); - - m_bDirty = true; - return m_objects.insert( __position, val ); -} - -// ----------------------------------------------------- -// -// ----------------------------------------------------- -void PdfArray::erase( const iterator& pos ) -{ - AssertMutable(); + PdfVecObjects *pOwner = GetObjectOwner(); + iterator it1 = __first; + iterator it2 = __position; + for ( ; it1 != __last; it1++, it2++ ) + { + it2 = m_objects.insert( it2, *it1 ); + if ( pOwner != NULL ) + it2->SetOwner( pOwner ); + } - m_objects.erase( pos ); m_bDirty = true; } // ----------------------------------------------------- // // ----------------------------------------------------- -void PdfArray::erase( const iterator& first, const iterator& last ) +void PdfArray::reserve( size_type __n ) { AssertMutable(); - m_objects.erase( first, last ); - m_bDirty = true; -} - -// ----------------------------------------------------- -// -// ----------------------------------------------------- -void PdfArray::reserve(size_type __n) -{ m_objects.reserve( __n ); } diff --git a/src/base/PdfDictionary.cpp b/src/base/PdfDictionary.cpp index df67c92..d43b211 100644 --- a/src/base/PdfDictionary.cpp +++ b/src/base/PdfDictionary.cpp @@ -44,9 +44,9 @@ PdfDictionary::PdfDictionary() } PdfDictionary::PdfDictionary( const PdfDictionary & rhs ) - : PdfDataType() + : PdfOwnedDataType() { - this->operator=( rhs ); + this->operator=( rhs ); m_bDirty = false; } @@ -68,7 +68,8 @@ const PdfDictionary & PdfDictionary::operator=( const PdfDictionary & rhs ) m_mapKeys[(*it).first] = new PdfObject( *(*it).second ); ++it; } - + + PdfOwnedDataType::operator=( rhs ); m_bDirty = true; return *this; } @@ -147,6 +148,9 @@ void PdfDictionary::AddKey( const PdfName & identifier, const PdfObject & rObjec inserted.first->second = objToInsert; } + PdfVecObjects *pOwner = GetObjectOwner(); + if ( pOwner != NULL ) + inserted.first->second->SetOwner( pOwner ); m_bDirty = true; } @@ -155,7 +159,7 @@ void PdfDictionary::AddKey( const PdfName & identifier, const PdfObject* pObject this->AddKey( identifier, *pObject ); } -const PdfObject* PdfDictionary::GetKey( const PdfName & key ) const +PdfObject * PdfDictionary::getKey( const PdfName & key ) const { if( !key.GetLength() ) return NULL; @@ -170,20 +174,43 @@ const PdfObject* PdfDictionary::GetKey( const PdfName & key ) const return (*it).second; } -PdfObject* PdfDictionary::GetKey( const PdfName & key ) +PdfObject * PdfDictionary::findKey( const PdfName &key ) const { - if( !key.GetLength() ) - return NULL; - - TIKeyMap it; - - it = m_mapKeys.find( key ); - - if( it == m_mapKeys.end() ) - return NULL; - - return (*it).second; -} + PdfObject *obj = getKey( key ); + if ( obj != NULL ) + { + if ( obj->IsReference() ) + return GetIndirectObject( obj->GetReference() ); + else + return obj; + } + + return NULL; +} + +PdfObject * PdfDictionary::findKeyParent( const PdfName & key ) const +{ + PdfObject *obj = findKey( key ); + if (obj == NULL) + { + PdfObject *parent = findKey( "Parent" ); + if ( parent == NULL ) + { + return NULL; + } + else + { + if ( parent->IsDictionary() ) + return parent->GetDictionary().findKeyParent( key ); + else + return NULL; + } + } + else + { + return obj; + } +} pdf_int64 PdfDictionary::GetKeyAsLong( const PdfName & key, pdf_int64 lDefault ) const { @@ -366,4 +393,18 @@ TCIKeyMap PdfDictionary::end() const return m_mapKeys.end(); } +void PdfDictionary::SetOwner( PdfObject *pOwner ) +{ + PdfOwnedDataType::SetOwner( pOwner ); + PdfVecObjects *pVecOwner = pOwner->GetOwner(); + if ( pVecOwner != NULL ) + { + // Set owmership for all children + TCIKeyMap it = this->begin(); + TCIKeyMap end = this->end(); + for ( ; it != end; it++ ) + it->second->SetOwner( pVecOwner ); + } +} + }; diff --git a/src/base/PdfDictionary.h b/src/base/PdfDictionary.h index 342d4fc..c2163a2 100644 --- a/src/base/PdfDictionary.h +++ b/src/base/PdfDictionary.h @@ -35,7 +35,7 @@ #define _PDF_DICTIONARY_H_ #include "PdfDefines.h" -#include "PdfDataType.h" +#include "PdfOwnedDataType.h" #include "PdfName.h" #include "PdfObject.h" @@ -86,7 +86,7 @@ class PdfOutputDevice; /** The PDF dictionary data type of PoDoFo (inherits from PdfDataType, * the base class for such representations) */ -class PODOFO_API PdfDictionary : public PdfDataType { +class PODOFO_API PdfDictionary : public PdfOwnedDataType { public: /** Create a new, empty dictionary */ @@ -165,7 +165,7 @@ class PODOFO_API PdfDictionary : public PdfDataType { * * \returns pointer to the found value, or 0 if the key was not found. */ - const PdfObject* GetKey( const PdfName & key ) const; + inline const PdfObject* GetKey( const PdfName & key ) const; /** Get the key's value out of the dictionary. This is an overloaded member * function. @@ -178,7 +178,32 @@ class PODOFO_API PdfDictionary : public PdfDataType { * * \returns the found value, or 0 if the key was not found. */ - PdfObject* GetKey( const PdfName & key ); + inline PdfObject* GetKey( const PdfName & key ); + + /** Get the keys value out of the dictionary + * + * Lookup in the indirect objects as well, if the shallow object was a reference. + * The returned value is a pointer to the internal object in the dictionary + * so it MUST not be deleted. + * + * \param key look for the key names pszKey in the dictionary + * \returns pointer to the found value or 0 if the key was not found. + */ + inline const PdfObject* FindKey( const PdfName & key ) const; + inline PdfObject* FindKey( const PdfName & key ); + + /** Get the keys value out of the dictionary + * + * Lookup in the indirect objects as well, if the shallow object was a reference. + * Also lookup the parent objects, if /Parent key is found in the dictionary. + * The returned value is a pointer to the internal object in the dictionary + * so it MUST not be deleted. + * + * \param key look for the key names pszKey in the dictionary + * \returns pointer to the found value or 0 if the key was not found. + */ + inline const PdfObject* FindKeyParent( const PdfName & key ) const; + inline PdfObject* FindKeyParent( const PdfName & key ); /** Get the key's value out of the dictionary. * @@ -286,6 +311,14 @@ class PODOFO_API PdfDictionary : public PdfDataType { TCIKeyMap begin() const; TCIKeyMap end() const; + protected: + void SetOwner( PdfObject* pOwner ); + + private: + PdfObject * getKey(const PdfName & key) const; + PdfObject * findKey(const PdfName & key) const; + PdfObject * findKeyParent(const PdfName & key) const; + private: TKeyMap m_mapKeys; @@ -296,6 +329,57 @@ typedef std::vector<PdfDictionary*> TVecDictionaries; typedef TVecDictionaries::iterator TIVecDictionaries; typedef TVecDictionaries::const_iterator TCIVecDictionaries; +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline const PdfObject * PdfDictionary::GetKey( const PdfName &key ) const +{ + return getKey(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline PdfObject * PdfDictionary::GetKey( const PdfName &key ) +{ + return getKey(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline const PdfObject * PdfDictionary::FindKey( const PdfName &key ) const +{ + return findKey(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline PdfObject * PdfDictionary::FindKey( const PdfName &key ) +{ + return findKey(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline const PdfObject* PdfDictionary::FindKeyParent( const PdfName &key ) const +{ + return findKeyParent(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- +inline PdfObject* PdfDictionary::FindKeyParent( const PdfName &key ) +{ + return findKeyParent(key); +} + +// ----------------------------------------------------- +// +// ----------------------------------------------------- size_t PdfDictionary::GetSize() const { return m_mapKeys.size(); diff --git a/src/base/PdfObject.cpp b/src/base/PdfObject.cpp index 91e8aff..09a2663 100644 --- a/src/base/PdfObject.cpp +++ b/src/base/PdfObject.cpp @@ -126,6 +126,8 @@ PdfObject::PdfObject( const PdfDictionary & rDict ) InitPdfObject(); } +// NOTE: Don't copy owner. Copied objects must be always detached. +// Ownership will be set automatically elsewhere PdfObject::PdfObject( const PdfObject & rhs ) : PdfVariant( rhs ), m_reference( rhs.m_reference ) { @@ -137,8 +139,12 @@ PdfObject::PdfObject( const PdfObject & rhs ) const_cast<PdfObject*>(&rhs)->DelayedStreamLoad(); m_bDelayedStreamLoadDone = rhs.DelayedStreamLoadDone(); - if( rhs.m_pStream && m_pOwner ) - m_pStream = m_pOwner->CreateStream( *(rhs.m_pStream) ); + // FIXME: + // Copying stream is currently broken: + // 1) PdfVecObjects::CreateStream( const PdfStream & ) is broken as it just returns NULL + // 2) Stream should be copyable also when m_pOwner is NULL (which is the case for copy constructor) + //if( rhs.m_pStream && m_pOwner ) + // m_pStream = m_pOwner->CreateStream( *(rhs.m_pStream) ); #if defined(PODOFO_EXTRA_CHECKS) // Must've been demand loaded or already done @@ -153,12 +159,46 @@ PdfObject::~PdfObject() m_pStream = NULL; } +void PdfObject::SetOwner( PdfVecObjects* pVecObjects ) +{ + PODOFO_ASSERT( pVecObjects != NULL ); + if ( m_pOwner == pVecObjects ) + { + // The inner owner for variant data objects is guaranteed to be same + return; + } + + m_pOwner = pVecObjects; + if ( DelayedLoadDone() ) + SetVariantOwner( GetDataType() ); +} + +void PdfObject::AfterDelayedLoad( EPdfDataType eDataType ) +{ + SetVariantOwner( eDataType ); +} + +void PdfObject::SetVariantOwner( EPdfDataType eDataType ) +{ + switch ( eDataType ) + { + case ePdfDataType_Dictionary: + static_cast<PdfOwnedDataType &>( GetDictionary_NoDL() ).SetOwner( this ); + break; + case ePdfDataType_Array: + static_cast<PdfOwnedDataType &>( GetArray_NoDL() ).SetOwner( this ); + break; + default: + break; + } +} + void PdfObject::InitPdfObject() { m_pStream = NULL; m_pOwner = NULL; - m_bDelayedStreamLoadDone = true; + SetVariantOwner( GetDataType() ); #if defined(PODOFO_EXTRA_CHECKS) m_bDelayedStreamLoadInProgress = false; @@ -221,26 +261,11 @@ void PdfObject::WriteObject( PdfOutputDevice* pDevice, EPdfWriteMode eWriteMode, PdfObject* PdfObject::GetIndirectKey( const PdfName & key ) const { - const PdfObject* pObj = NULL; - - if( this->IsDictionary() && this->GetDictionary().HasKey( key ) ) - { - pObj = this->GetDictionary().GetKey( key ); - if( pObj->IsReference() ) - { - if( !m_pOwner ) - { - PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "Object is a reference but does not have an owner!" ); - } - - pObj = m_pOwner->GetObject( pObj->GetReference() ); - } - else - const_cast<PdfObject*>(pObj)->SetOwner( GetOwner() );// even directs might want an owner... - } + if ( !this->IsDictionary() ) + return NULL; // DominikS: TODO Remove const on GetIndirectKey - return const_cast<PdfObject*>(pObj); + return const_cast<PdfObject*>( this->GetDictionary().FindKey( key ) ); } pdf_long PdfObject::GetObjectLength( EPdfWriteMode eWriteMode ) @@ -314,15 +339,18 @@ const PdfObject & PdfObject::operator=( const PdfObject & rhs ) const_cast<PdfObject*>(&rhs)->DelayedStreamLoad(); + // NOTE: Don't copy owner. Objects being assigned always keep current ownership + PdfVariant::operator=(rhs); m_reference = rhs.m_reference; - m_pOwner = rhs.m_pOwner; - - PdfVariant::operator=( rhs ); - m_bDelayedStreamLoadDone = rhs.DelayedStreamLoadDone(); - - if( rhs.m_pStream ) - m_pStream = m_pOwner->CreateStream( *(rhs.m_pStream) ); + SetVariantOwner( GetDataType() ); + + // FIXME: + // Copying stream is currently broken: + // 1) PdfVecObjects::CreateStream( const PdfStream & ) is broken as it just returns NULL + // 2) Stream should be copyable also when m_pOwner is NULL + //if( rhs.m_pStream ) + // m_pStream = m_pOwner->CreateStream( *(rhs.m_pStream) ); #if defined(PODOFO_EXTRA_CHECKS) // Must've been demand loaded or already done diff --git a/src/base/PdfObject.h b/src/base/PdfObject.h index 8ed71a4..3ad042f 100644 --- a/src/base/PdfObject.h +++ b/src/base/PdfObject.h @@ -48,6 +48,9 @@ class PdfObject; class PdfOutputDevice; class PdfStream; class PdfVecObjects; +class PdfDictionary; +class PdfArray; +class PdfDocument; /** * This class represents a PDF indirect Object in memory @@ -63,6 +66,9 @@ class PdfVecObjects; */ class PODOFO_API PdfObject : public PdfVariant { friend class PdfVecObjects; + friend class PdfArray; + friend class PdfDictionary; + friend class PdfDocument; public: @@ -234,13 +240,6 @@ class PODOFO_API PdfObject : public PdfVariant { */ PODOFO_NOTHROW inline bool operator==( const PdfObject & rhs ) const; - /** Set the owner of this object, i.e. the PdfVecObjects to which - * this object belongs. - * - * \param pVecObjects a vector of pdf objects - */ - inline void SetOwner( PdfVecObjects* pVecObjects ); - /** Get the owner of this object. * \return the creator of this object */ @@ -318,6 +317,20 @@ class PODOFO_API PdfObject : public PdfVariant { */ PdfStream* GetStream_NoDL(); + virtual void AfterDelayedLoad( EPdfDataType eDataType ); + + /** Set the owner of this object variant + */ + void SetVariantOwner( EPdfDataType eDataType ); + + private: + /** Set the owner of this object, i.e. the PdfVecObjects to which + * this object belongs. + * + * \param pVecObjects a vector of pdf objects + */ + void SetOwner(PdfVecObjects* pVecObjects); + private: /* See PdfVariant.h for a detailed explanation of this member, which is * here to prevent accidental construction of a PdfObject of integer type @@ -378,14 +391,6 @@ const PdfReference & PdfObject::Reference() const return m_reference; } -// ----------------------------------------------------- -// -// ----------------------------------------------------- -inline void PdfObject::SetOwner( PdfVecObjects* pVecObjects ) -{ - m_pOwner = pVecObjects; -} - // ----------------------------------------------------- // // ----------------------------------------------------- diff --git a/src/base/PdfOwnedDataType.cpp b/src/base/PdfOwnedDataType.cpp new file mode 100644 index 0000000..81c7f63 --- /dev/null +++ b/src/base/PdfOwnedDataType.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2006 by Dominik Seichter * + * domseich...@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + * In addition, as a special exception, the copyright holders give * + * permission to link the code of portions of this program with the * + * OpenSSL library under certain conditions as described in each * + * individual source file, and distribute linked combinations * + * including the two. * + * You must obey the GNU General Public License in all respects * + * for all of the code used other than OpenSSL. If you modify * + * file(s) with this exception, you may extend this exception to your * + * version of the file(s), but you are not obligated to do so. If you * + * do not wish to do so, delete this exception statement from your * + * version. If you delete this exception statement from all source * + * files in the program, then also delete it here. * + ***************************************************************************/ + +#include "PdfOwnedDataType.h" +#include "PdfObject.h" +#include "PdfVecObjects.h" + +namespace PoDoFo { + +PdfOwnedDataType::PdfOwnedDataType() + : m_pOwner( NULL ) +{ +} + +// NOTE: Don't copy owner. Copied objects must be always detached. +// Ownership will be set automatically elsewhere +PdfOwnedDataType::PdfOwnedDataType( const PdfOwnedDataType &rhs ) + : PdfDataType( rhs ), m_pOwner( NULL ) +{ +} + +PdfObject * PdfOwnedDataType::GetIndirectObject( const PdfReference &rReference ) const +{ + if ( m_pOwner == NULL ) + PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "Object is a reference but does not have an owner!" ); + + return m_pOwner->GetOwner()->GetObject( rReference ); +} + +void PdfOwnedDataType::SetOwner( PdfObject* pOwner ) +{ + PODOFO_ASSERT( pOwner != NULL ); + m_pOwner = pOwner; +} + +PdfOwnedDataType & PdfOwnedDataType::operator=( const PdfOwnedDataType & rhs ) +{ + // NOTE: Don't copy owner. Objects being assigned will keep current ownership + PdfDataType::operator=( rhs ); + return *this; +} + +PdfVecObjects * PdfOwnedDataType::GetObjectOwner() +{ + return m_pOwner == NULL ? NULL : m_pOwner->GetOwner(); +} + +}; diff --git a/src/base/PdfOwnedDataType.h b/src/base/PdfOwnedDataType.h new file mode 100644 index 0000000..eeb3e8d --- /dev/null +++ b/src/base/PdfOwnedDataType.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2006 by Dominik Seichter * + * domseich...@web.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + * In addition, as a special exception, the copyright holders give * + * permission to link the code of portions of this program with the * + * OpenSSL library under certain conditions as described in each * + * individual source file, and distribute linked combinations * + * including the two. * + * You must obey the GNU General Public License in all respects * + * for all of the code used other than OpenSSL. If you modify * + * file(s) with this exception, you may extend this exception to your * + * version of the file(s), but you are not obligated to do so. If you * + * do not wish to do so, delete this exception statement from your * + * version. If you delete this exception statement from all source * + * files in the program, then also delete it here. * + ***************************************************************************/ + +#ifndef _PDF_OWNED_DATATYPE_H_ +#define _PDF_OWNED_DATATYPE_H_ + +#include "PdfDataType.h" + +namespace PoDoFo { + +class PdfObject; +class PdfVecObjects; +class PdfReference; + +/** + * A PdfDataType object with PdfObject owner + */ +class PODOFO_API PdfOwnedDataType : public PdfDataType { + friend class PdfObject; +protected: + /** Create a new PdfDataOwnedType. + * Can only be called by subclasses + */ + PdfOwnedDataType(); + + PdfOwnedDataType( const PdfOwnedDataType &rhs ); + +public: + + /** \returns a pointer to a PdfVecObjects that is the + * owner of this data type. + * Might be NULL if the data type has no owner. + */ + inline PdfObject* GetOwner() const; + + PdfOwnedDataType & operator=( const PdfOwnedDataType &rhs ); + +protected: + PdfObject * GetIndirectObject( const PdfReference &rReference ) const; + PdfVecObjects * GetObjectOwner(); + virtual void SetOwner( PdfObject *pOwner ); + +private: + PdfObject *m_pOwner; +}; + +inline PdfObject* PdfOwnedDataType::GetOwner() const +{ + return m_pOwner; +} + +}; // namespace PoDoFo + +#endif /* _PDF_OWNED_DATATYPE_H_ */ diff --git a/src/base/PdfVariant.h b/src/base/PdfVariant.h index 97e1745..32b455d 100644 --- a/src/base/PdfVariant.h +++ b/src/base/PdfVariant.h @@ -436,6 +436,11 @@ class PODOFO_API PdfVariant { */ inline virtual void DelayedLoadImpl(); + /** Called after delayed load + * \param eDataType Detected data type + */ + inline virtual void AfterDelayedLoad( EPdfDataType eDataType ); + /** * Returns true if delayed loading is disabled, or if it is enabled * and loading has completed. External callers should never need to @@ -562,6 +567,7 @@ inline void PdfVariant::DelayedLoad() const #if defined(PODOFO_EXTRA_CHECKS) m_bDelayedLoadInProgress = false; #endif + const_cast<PdfVariant*>(this)->AfterDelayedLoad( m_eDataType ); } } @@ -940,6 +946,15 @@ void PdfVariant::DelayedLoadImpl() PODOFO_RAISE_ERROR( ePdfError_InternalLogic ); } +// ----------------------------------------------------- +// +// ----------------------------------------------------- +void PdfVariant::AfterDelayedLoad( EPdfDataType eDataType ) +{ + ( void )eDataType; + // Do nothing +} + // ----------------------------------------------------- // // ----------------------------------------------------- diff --git a/src/doc/PdfPage.cpp b/src/doc/PdfPage.cpp index f021ce7..0842e09 100644 --- a/src/doc/PdfPage.cpp +++ b/src/doc/PdfPage.cpp @@ -720,11 +720,7 @@ PdfObject* PdfPage::GetOwnAnnotationsArray( bool bCreate, PdfDocument *pDocument } pObj = pDocument->GetObjects()->GetObject( pObj->GetReference() ); - if(pObj) { - pObj->SetOwner(this->GetObject()->GetOwner()); - } - } else - pObj->SetOwner( this->GetObject()->GetOwner() );// even directs might want an owner... + } } if( pObj && pObj->IsArray() ) diff --git a/src/doc/PdfShadingPattern.cpp b/src/doc/PdfShadingPattern.cpp index 9527511..8a91f4c 100644 --- a/src/doc/PdfShadingPattern.cpp +++ b/src/doc/PdfShadingPattern.cpp @@ -186,7 +186,6 @@ void PdfShadingPattern::Init( EPdfShadingPatternType eShadingType ) } else { PdfObject *shadingObject = this->GetObject()->GetOwner()->CreateObject(shading); this->GetObject()->GetDictionary().AddKey(PdfName("Shading"), shadingObject->Reference()); - this->GetObject()->GetDictionary().GetKey(PdfName("Shading"))->SetOwner(this->GetObject()->GetOwner()); } }
_______________________________________________ Podofo-users mailing list Podofo-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/podofo-users