From: Francesco Pretto <[email protected]>
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 *
+ * [email protected] *
+ * *
+ * 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 *
+ * [email protected] *
+ * *
+ * 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users