From: Michal H. <ms...@gm...> - 2008-04-04 16:06:33
|
CPdf is referenced from properties by weak_ptr which with combination with CPdf::getInstance returning shared_ptr guarantees that propeties are never used after CPdf is destroyed. Thanks Jozo for weak_ptr pattern idea and implementation howto. cobjects works only with weak_ptr<CPdf> and higher level functions still use smart_ptr (so they can be used by normal code without knowing anything about weak_ptr). Error on weak_ptr::lock is handled like if pdf is not valid. It is important to realize that CPdf::_this can't be used in destructor because it is no more valid at that moment! shared_ptr for this weak_ptr is no more valid (we are in destructor called from its deleter). This is problem especially for page tree observers which need to be unregistered (and so need to dereference properties). To handle that as easy as possible the new observer deactivation feature is used. So we know for sure that they are never triggered and can't be harmful. Normally all properties (including page tree nodes) should be deallocated in destructor and if there are references from outside (e.g. from scripting wrappers) then we have no problem. Kernel: ======= * IProperty - pdf is not stored as pointer but rather weak_ptr<CPdf> - constructors take weak_ptr rather than CPdf* - {get,set}Pdf {returns,sets} weak_ptr instead of CPdf* - signature changed to contain weak_ptr rather than CPdf*: isPdfValid * carray.{cc,h}, cdict.{cc,h}, ccontentstream.cc, cobjecthelpers.cc, cpage.cc, cpageannots.cc, cpagedisplay.cc - sync with IProperty change * cobject2xpdf.{cc,h} - sync with IProperty change - createObjFromXpdfObj signature change (CPdf* -> weak_ptr<CPdf>) * cobjectsimple.h, cobjectsimpleI.h, cstream.{cc,h}, cinlineimage.{cc,h}, cpagecontents.{cc,h} - signature changed (CPdf& -> weak_ptr<CPdf>): constructor, createObjFromXpdfObj, setPdf, createStreamFromObjects * pdfoperators.{cc,h}, pdfoperatorsbase.{cc,h}, - signature changed (CPdf* -> weak_ptr<CPdf>): init_operands, * cpdf.{cc,h} - new _this field which holds weak reference, set in CPdf::getInstance and used for initializaton properties - destructor doesn't unregister page tree observers and rather deactivate them to prevent from invalid access to _this (which is no more valid at that moment because shared_ptr has expired) which is needed for unregisterPageObservers. indMap is cleared before destructor is done (to release all indirect properties). - sync with IProperty change (getPdf) - signature changed to contain shared_ptr rather than CPdf*: getPageTreeRoot, getNodeType, discardKidsCountCache, searchTreeNode, getNodePosition, isDescendant, isEncrypted, - DEPRECATED getCObjectFromRef with CPdf parameter removed (they aren't used anywhere in the code) * factories.h - all factory methods use smart_ptr GUI: ==== * additemdialog.{cc,h}, refproperty.{cc,h}, refpropertydialog.{cc,h}, - pdf changed from CPdf* -> shared_ptr<CPdf> * refpropertydialog.{cc,h} - pdf changed from CPdf* -> weak_ptr<CPdf> - RefProperty seems to be only one user of this dialog, so I didn't transformed it to standard high level smart_ptr * pdfutil.{cc,h} - signature changed (CPdf* -> shared_ptr<CPdf>): isRefValid, * pdfeditwindow.cc, treeitempage.cc, treeitemref.cc, qspdf.cc, treeitempdf.cc - sync with kernel changes TESTS: ====== synced with kernel changes Index: src/kernel/cpdf.cc =================================================================== --- src/kernel/cpdf.cc.orig 2008-04-03 18:48:18.000000000 +0200 +++ src/kernel/cpdf.cc 2008-04-04 15:46:13.000000000 +0200 @@ -80,13 +80,13 @@ ostream & operator<<(ostream & stream, P return stream; } -shared_ptr<CDict> getPageTreeRoot(const CPdf & pdf) +shared_ptr<CDict> getPageTreeRoot(const boost::shared_ptr<CPdf> &pdf) { shared_ptr<CDict> result; try { - shared_ptr<IProperty> pagesProp=pdf.getDictionary()->getProperty("Pages"); + shared_ptr<IProperty> pagesProp=pdf->getDictionary()->getProperty("Pages"); if(!isRef(pagesProp)) // returns null dictionary return result; @@ -100,7 +100,7 @@ shared_ptr<CDict> getPageTreeRoot(const return result; } -PageTreeNodeType getNodeType(const boost::shared_ptr<IProperty> & nodeProp)throw() +PageTreeNodeType getNodeType(const boost::shared_ptr<IProperty> &nodeProp)throw() { PageTreeNodeType nodeType=UnknownNode; @@ -125,9 +125,9 @@ PageTreeNodeType getNodeType(const boost return ErrorNode; // checks root node at first - CPdf * pdf=nodeProp->getPdf(); + shared_ptr<CPdf> pdf=nodeProp->getPdf().lock(); assert(pdf); - shared_ptr<CDict> rootDict=getPageTreeRoot(*pdf); + shared_ptr<CDict> rootDict=getPageTreeRoot(pdf); if(rootDict==nodeDict) // root dictionary found and it is same as internode return RootNode; @@ -329,7 +329,7 @@ void clearCache(CacheType & cache) */ void discardKidsCountCache( IndiRef & ref, - CPdf & pdf, + boost::shared_ptr<CPdf> pdf, PageTreeNodeCountCache & cache, bool withSubTree=false) { @@ -340,7 +340,7 @@ using namespace debug; if(!withSubTree) return; - shared_ptr<IProperty> nodeProp=pdf.getIndirectProperty(ref); + shared_ptr<IProperty> nodeProp=pdf->getIndirectProperty(ref); if(getNodeType(nodeProp)>=InterNode) { ChildrenStorage childs; @@ -424,7 +424,7 @@ size_t getKidsCount(const boost::shared_ } boost::shared_ptr<CDict> findPageDict( - const CPdf & pdf, + const boost::shared_ptr<CPdf> &pdf, boost::shared_ptr<IProperty> pagesDict, size_t startPos, size_t pos, PageTreeNodeCountCache * cache) @@ -631,7 +631,7 @@ boost::shared_ptr<CDict> findPageDict( * superNode. */ size_t searchTreeNode( - const CPdf & pdf, + shared_ptr<const CPdf> pdf, shared_ptr<CDict> superNode, shared_ptr<CDict> node, size_t startValue, @@ -734,11 +734,11 @@ size_t searchTreeNode( return position; } -size_t getNodePosition(const CPdf & pdf, shared_ptr<IProperty> node, PageTreeNodeCountCache * cache) +size_t getNodePosition(const shared_ptr<CPdf> &pdf, shared_ptr<IProperty> node, PageTreeNodeCountCache * cache) { utilsPrintDbg(DBG_DBG, ""); // node must be from given pdf - if(node->getPdf()!=&pdf) + if(node->getPdf().lock()!=pdf) { utilsPrintDbg(DBG_ERR, "Node is not from given pdf isntance."); throw PageNotFoundException(0); @@ -775,7 +775,7 @@ size_t getNodePosition(const CPdf & pdf, throw PageNotFoundException(0); } -bool isDescendant(CPdf & pdf, IndiRef parent, shared_ptr<CDict> child) +bool isDescendant(boost::shared_ptr<CPdf> pdf, IndiRef parent, shared_ptr<CDict> child) { using namespace utils; @@ -812,12 +812,12 @@ using namespace utils; } } -bool isEncrypted(CPdf & pdf, string * filterName) +bool isEncrypted(boost::shared_ptr<CPdf> &pdf, string * filterName) { utilsPrintDbg(DBG_DBG, ""); // gets trailer dictionary and checks Encrypt entry - shared_ptr<const CDict> trailer=pdf.getTrailer(); + shared_ptr<const CDict> trailer=pdf->getTrailer(); if(! trailer->containsProperty("Encrypt")) { utilsPrintDbg(DBG_DBG, "Document content is not encrypted."); @@ -988,7 +988,7 @@ using namespace pdfobjects::utils; bool unregister=true; try { - unregister=!getNodePosition(*this, dict_ptr, &nodeCountCache); + unregister=!getNodePosition(_this.lock(), dict_ptr, &nodeCountCache); }catch(AmbiguousPageTreeException &) { // node is still in the tree and even more it is still ambiguous @@ -1084,6 +1084,7 @@ using namespace debug; using namespace observer; using namespace utils; + assert(isActive()); shared_ptr<IProperty> oldValue; if(!context) { @@ -1218,6 +1219,7 @@ using namespace debug; using namespace boost; using namespace observer; + assert(isActive()); if(!context) { kernelPrintDbg(DBG_WARN, "No context available. Ignoring calling."); @@ -1402,6 +1404,7 @@ using namespace boost; using namespace debug; using namespace utils; + assert(isActive()); if(!context) { kernelPrintDbg(DBG_WARN, "No context available. Ignoring calling."); @@ -1559,7 +1562,7 @@ using namespace utils; { IndiRef oldRef=getValueFromSimple<CRef>(oldValue); kernelPrintDbg(DBG_DBG, "discarding leaf count cache for "<<oldRef<<" subtree"); - discardKidsCountCache(oldRef, *pdf, pdf->nodeCountCache, true); + discardKidsCountCache(oldRef, pdf->_this.lock(), pdf->nodeCountCache, true); } // if newValue is reference, registers observers to newValue dereferenced @@ -1601,7 +1604,7 @@ using namespace observer; if(isRef(pagesProp)) { UNREGISTER_SHAREDPTR_OBSERVER(pagesProp, pageTreeRootObserver); - shared_ptr<IProperty> pageTreeRoot=getPageTreeRoot(*this); + shared_ptr<IProperty> pageTreeRoot=getPageTreeRoot(_this.lock()); if(pageTreeRoot.get()) { try @@ -1722,7 +1725,7 @@ using namespace observer; // registers pageTreeNodeObserver and pageTreeKidsObserver to page tree root // dictionary which registers these observers to whole page tree structure - shared_ptr<IProperty> pageTreeRoot=getPageTreeRoot(*this); + shared_ptr<IProperty> pageTreeRoot=getPageTreeRoot(_this.lock()); if(pageTreeRoot.get()) registerPageTreeObservers(pageTreeRoot); } @@ -1736,12 +1739,11 @@ CPdf::CPdf(StreamWriter * stream, OpenMo modeController(NULL) { // gets xref writer - if error occures, exception is thrown + // Note that we can't do anything that could use cobjects here + // because of weak_ptr & shared_ptr are not initialized yet xref=new XRefWriter(stream, this); mode=openMode; - // initializes revision specific data for the newest revision - initRevisionSpecific(); - // sets mode accoring openMode // ReadOnly and ReadWrite implies xref paranoid mode (default one) // whereas Advanced mode sets easy mode because we want to have full @@ -1850,9 +1852,19 @@ CPdf::~CPdf() } pageList.clear(); - // unregisters all observers registered on page tree nodes (root, - // intermediate and leaf nodes) - unregisterPageObservers(); + // idealy we should unregister page tree observers but as the _this + // is no longer valid in this context (last reference to + // shared_ptr<CPdf> was dropped) we can't call unregisterPageObservers + // which relies on it (like everything which uses weak_ptr to this + // instance) - we will rather mark all types of observers are invalid + // so they do nothing if they are triggered - which should not happen + // anyway + pageTreeRootObserver->setActive(false); + pageTreeNodeObserver->setActive(false); + pageTreeKidsObserver->setActive(false); + + // clears all referenced indirect properties + indMap.clear(); // clean up resolved reference mapping for different pdf objects for(ResolvedRefMapping::iterator i=resolvedRefMapping.begin(); @@ -1908,7 +1920,7 @@ using namespace debug; // the mapping if(obj.getType()!=objNull) { - IProperty * prop=utils::createObjFromXpdfObj(*this, obj, ref); + IProperty * prop=utils::createObjFromXpdfObj(_this.lock(), obj, ref); prop_ptr=shared_ptr<IProperty>(prop); indMap.insert(IndirectMapping::value_type(ref, prop_ptr)); kernelPrintDbg(DBG_INFO, "Mapping created for "<<ref); @@ -1940,8 +1952,8 @@ using namespace utils; // so no type check fails). We have to set this pdf temporarily, because // _makeXpdfObject function sets xref to created Object from ip->getPdf(). // Finally restores original pdf value - CPdf * original=ip->getPdf(); - ip->setPdf(this); + shared_ptr<CPdf> original=ip->getPdf().lock(); + ip->setPdf(_this); ::Object * obj=ip->_makeXpdfObject(); ip->setPdf(original); kernelPrintDbg(DBG_DBG, "Initializating object with type="<<obj->getType()<<" to reserved reference "<<ref); @@ -2042,7 +2054,7 @@ using namespace utils; IndiRef invalidRef; // this method makes sense only for properties from different pdf - assert(this!=ip->getPdf()); + assert(_this.lock()!=ip->getPdf().lock()); kernelPrintDbg(debug::DBG_DBG,"property type=" <<ip->getType()<<" ResolvedRefStorage size=" @@ -2086,7 +2098,9 @@ using namespace utils; kernelPrintDbg(DBG_DBG, "Following reference "<<ipRef<<" mapped to " <<refEntry->first); // ip is from read pdf and so dereferences target value - shared_ptr<IProperty> followedIp=ip->getPdf()->getIndirectProperty(ipRef); + // FIXME check for valid pdf + shared_ptr<CPdf> pdf = ip->getPdf().lock(); + shared_ptr<IProperty> followedIp=pdf->getIndirectProperty(ipRef); // adds dereferenced value using addProperty with collected // container. Current mapping is set to resolving state to @@ -2169,7 +2183,8 @@ using namespace boost; } // checks whether given ip is from same pdf - if(ip->getPdf()==this) + shared_ptr<CPdf> ipPdf = ip->getPdf().lock(); + if(ipPdf.get()==this) { // ip is from same pdf and so all possible referencies are already in // pdf too. We can clearly register with given indiRef @@ -2183,7 +2198,7 @@ using namespace boost; // pdf==null - prop from no pdf - then uses NO_PDF_ID constant). // It contains mappings from such pdf indirect reference to coresponding // newly created reference for this pdf. - cpdf_id_t id=(ip->getPdf())?ip->getPdf()->getId():CPdf::NO_PDF_ID; + cpdf_id_t id=(ipPdf)?ipPdf->getId():CPdf::NO_PDF_ID; ResolvedRefMapping::iterator i=resolvedRefMapping.find(id); ResolvedRefStorage * resolvedStorage; if(i==resolvedRefMapping.end()) @@ -2267,7 +2282,7 @@ void CPdf::changeIndirectProperty(boost: // checks property at first // it must be from same pdf - if(prop->getPdf() != this) + if(prop->getPdf().lock() != _this.lock()) { kernelPrintDbg(DBG_ERR, "Given property is not from same pdf."); throw CObjInvalidObject(); @@ -2356,6 +2371,12 @@ using namespace std; try { shared_ptr<CPdf> instance(new CPdf(stream, mode), PdfDeleter()); + instance->_this = instance; + + // initializes revision specific data for the newest revision + // We can't do it in constructor because we are using cobjects + // there and thus shared_ptr and _this have to be initialized + instance->initRevisionSpecific(); // We don't want to enable editing linearized documents because // it leads to almost 100% damage of content - we are not able @@ -2420,10 +2441,10 @@ using namespace utils; // page is not available in pageList, searching has to be done // find throws an exception if any problem found, otherwise pageDict_ptr // contians Page dictionary at specified position. - shared_ptr<CDict> rootPages_ptr=getPageTreeRoot(*this); + shared_ptr<CDict> rootPages_ptr=getPageTreeRoot(_this.lock()); if(!rootPages_ptr.get()) throw PageNotFoundException(pos); - shared_ptr<CDict> pageDict_ptr=findPageDict(*this, rootPages_ptr, 1, pos, &nodeCountCache); + shared_ptr<CDict> pageDict_ptr=findPageDict(_this.lock(), rootPages_ptr, 1, pos, &nodeCountCache); // creates CPage instance from page dictionary and stores it to the pageList CPage * page=CPageFactory::getInstance(pageDict_ptr); @@ -2448,7 +2469,7 @@ using namespace utils; return pageCount; } - shared_ptr<CDict> rootDict=getPageTreeRoot(*this); + shared_ptr<CDict> rootDict=getPageTreeRoot(_this.lock()); if(!rootDict.get()) return 0; return pageCount=getKidsCount(rootDict, &nodeCountCache); @@ -2582,7 +2603,7 @@ using namespace utils; shared_ptr<CPage> page=i->second; // checks page's dictionary whether it is in oldDict_ptr sub // tree and if so removes it from pageList - if(isDescendant(*this, ref, page->getDictionary())) + if(isDescendant(_this.lock(), ref, page->getDictionary())) { // sets flag, that at least one descendants is found found=true; @@ -2649,7 +2670,7 @@ using namespace utils; // no information try { - minPos = getNodePosition(*this, newValue, &nodeCountCache); + minPos = getNodePosition(_this.lock(), newValue, &nodeCountCache); }catch(exception &e) { // position can't be determined @@ -2701,7 +2722,7 @@ using namespace utils; // means that it can't be determined. Such page is invalidated. try { - size_t pos=getNodePosition(*this, i->second->getDictionary(), &nodeCountCache); + size_t pos=getNodePosition(_this.lock(), i->second->getDictionary(), &nodeCountCache); kernelPrintDbg(DBG_DBG, "Original position="<<i->first<<" new="<<pos); pageList.insert(PageList::value_type(pos, i->second)); }catch(AmbiguousPageTreeException & e) @@ -2738,7 +2759,7 @@ using namespace utils; kernelPrintDbg(DBG_DBG, ""); // gets pdf of the node - must be non null - assert(interNode->getPdf()); + assert(interNode->getPdf().lock()); // only internode make sense to consolidate PageTreeNodeType nodeType=getNodeType(interNode); @@ -2809,7 +2830,7 @@ using namespace utils; // in subtree (they contain correct values because change was just in this // intermediate node) if(countChanged) - discardKidsCountCache(interNodeRef, *this, nodeCountCache, false); + discardKidsCountCache(interNodeRef, _this.lock(), nodeCountCache, false); kernelPrintDbg(DBG_DBG, "consolidating Kids array members"); @@ -2956,7 +2977,7 @@ using namespace utils; shared_ptr<CDict> interNode_ptr; shared_ptr<CRef> currRef; // by default it is root of page tree - interNode_ptr=getPageTreeRoot(*this); + interNode_ptr=getPageTreeRoot(_this.lock()); if(!interNode_ptr.get()) { // Root of page dictionary doesn't exist @@ -2969,7 +2990,7 @@ using namespace utils; // searches for page at storePosition and gets its reference // page dictionary has to be an indirect object, so getIndiRef returns // dictionary reference - shared_ptr<CDict> currentPage_ptr=findPageDict(*this, interNode_ptr, 1, storePostion, &nodeCountCache); + shared_ptr<CDict> currentPage_ptr=findPageDict(_this.lock(), interNode_ptr, 1, storePostion, &nodeCountCache); currRef=shared_ptr<CRef>(CRefFactory::getInstance(currentPage_ptr->getIndiRef())); // gets parent of found dictionary which maintains @@ -3008,12 +3029,12 @@ using namespace utils; // Now it is safe to add indirect object, because there is nothing that can // fail shared_ptr<CDict> pageDict=page->getDictionary(); - if(pageDict->getPdf() && pageDict->getPdf()!=this) + shared_ptr<CPdf> pageDictPdf = pageDict->getPdf().lock(); + if(pageDictPdf && pageDictPdf !=_this.lock()) { // page comes from different valid pdf - we have to create clone and // remove Parent field from it. Also inheritable properties have to be // handled - CPdf * pageDictPdf=pageDict->getPdf(); IndiRef pageDictIndiRef=pageDict->getIndiRef(); pageDict=IProperty::getSmartCObjectPtr<CDict>(pageDict->clone()); pageDict->delProperty("Parent"); @@ -3071,8 +3092,8 @@ using namespace utils; // Searches for page dictionary at given pos and gets its reference. // getPageTreeRoot doesn't fail, because we are in page range and so it has // to exist - shared_ptr<CDict> rootDict=getPageTreeRoot(*this); - shared_ptr<CDict> currentPage_ptr=findPageDict(*this, rootDict, 1, pos, &nodeCountCache); + shared_ptr<CDict> rootDict=getPageTreeRoot(_this.lock()); + shared_ptr<CDict> currentPage_ptr=findPageDict(_this.lock(), rootDict, 1, pos, &nodeCountCache); shared_ptr<CRef> currRef(CRefFactory::getInstance(currentPage_ptr->getIndiRef())); // Gets parent field from found page dictionary and gets its Kids array Index: src/kernel/cpdf.h =================================================================== --- src/kernel/cpdf.h.orig 2008-04-03 18:48:18.000000000 +0200 +++ src/kernel/cpdf.h 2008-04-04 15:46:13.000000000 +0200 @@ -1010,6 +1010,11 @@ private: */ configuration::ModeController* modeController; + /** Weak reference to this instance for proper reference counting + * with combination to published shared_ptr. + */ + boost::weak_ptr<CPdf> _this; + /** Empty constructor. * * This constructor is disabled, because we want to prevent uninitialized @@ -1658,7 +1663,7 @@ enum PageTreeNodeType { ErrorNode, Unkno * * @return Dictionary wrapped by shared_ptr (NULL dictionary if not found). */ -boost::shared_ptr<CDict> getPageTreeRoot(const CPdf & pdf); +boost::shared_ptr<CDict> getPageTreeRoot(const boost::shared_ptr<CPdf> &pdf); /** Helper method to find page at certain position. * @param pdf Pdf instance where to search. @@ -1732,7 +1737,7 @@ boost::shared_ptr<CDict> getPageTreeRoot * position. */ boost::shared_ptr<CDict> findPageDict( - const CPdf & pdf, + const boost::shared_ptr<CPdf> &pdf, boost::shared_ptr<IProperty> pagesDict, size_t startPos, size_t pos, @@ -1761,7 +1766,9 @@ boost::shared_ptr<CDict> findPageDict( * of page tree ambiguity (see searchTreeNode for more information). * @return Node position. */ -size_t getNodePosition(const CPdf & pdf, boost::shared_ptr<IProperty> node, PageTreeNodeCountCache * cache); +size_t getNodePosition(const boost::shared_ptr<CPdf> &pdf, + boost::shared_ptr<IProperty> node, + PageTreeNodeCountCache * cache); /** Calculates number of direct pages under given node property. * @param interNodeProp Page tree node property (must be dictionary or reference @@ -1826,7 +1833,7 @@ PageTreeNodeType getNodeType(const boost * * @return true If given child belongs to parent subtree, false otherwise. */ -bool isDescendant(CPdf & pdf, IndiRef parent, boost::shared_ptr<CDict> child); +bool isDescendant(boost::shared_ptr<CPdf> pdf, IndiRef parent, boost::shared_ptr<CDict> child); /** Collects all kids elements from internode dictionary. * @param interNodeDict Intermediate node dictionary. @@ -1856,71 +1863,7 @@ void getKidsFromInterNode(const boost::s * * @return true if file content is encrypted, false otherwise. */ -bool isEncrypted(CPdf & pdf, std::string * filterName); - -/** Returns cobjects from given reference property. - * @param refProp Reference property (must be pRef typed). - * - * Gets reference value from property and dereferences indirect object from it. - * Uses refProp's pdf for dereference (so it has to be valid). - * Checks target object for given template pType and if it matches casts it to - * given CType and returns. - * - * @throw ElementBadTypeException if refProp is not CRef instance or indirect - * object is not CType instance. - * @return CType instance wrapped by shared_ptr smart pointer. - */ -template<typename CType, PropertyType pType> -boost::shared_ptr<CType> getCObjectFromRef(boost::shared_ptr<IProperty> refProp)DEPRECATED; - -// gcc doesn't like __attribute__ in function definition -template<typename CType, PropertyType pType> -boost::shared_ptr<CType> getCObjectFromRef(boost::shared_ptr<IProperty> refProp) -{ - // REMARK - // This helper has to be here because of gcc template manipulation - // (cobjecthelpers.h can't include from this header file) - - if(!isRef(refProp)) - throw ElementBadTypeException(""); - - // gets reference value and dereferences indirect object - assert(refProp->getPdf()); - assert(hasValidRef(refProp)); - IndiRef ref; - IProperty::getSmartCObjectPtr<CRef>(refProp)->getValue(ref); - boost::shared_ptr<IProperty> indirect_ptr=refProp->getPdf()->getIndirectProperty(ref); - if(indirect_ptr->getType() != pType) - throw ElementBadTypeException(""); - return IProperty::getSmartCObjectPtr<CType>(indirect_ptr); -} - -/** Returns cobjects from given reference and pdf. - * @param ref Indirect reference. - * @param pdf CPdf instance where to fetch. - * - * Calls getIndirectProperty on given pdf and cast returned indirect object to - * given CType. - * - * @throw ElementBadTypeException if indirect object is not CType instance. - * @return CType instance wrapped by shared_ptr smart pointer. - */ -template<typename CType, PropertyType pType> -boost::shared_ptr<CType> getCObjectFromRef(IndiRef ref, CPdf & pdf)DEPRECATED; - -// gcc doesn't like __attribute__ in function definition -template<typename CType, PropertyType pType> -boost::shared_ptr<CType> getCObjectFromRef(IndiRef ref, CPdf & pdf) -{ - // REMARK - // This helper has to be here because of gcc template manipulation - // (cobjecthelpers.h can't include from this header file) - - boost::shared_ptr<IProperty> indirect_ptr=pdf.getIndirectProperty(ref); - if(indirect_ptr->getType() != pType) - throw ElementBadTypeException(""); - return IProperty::getSmartCObjectPtr<CType>(indirect_ptr); -} +bool isEncrypted(boost::shared_ptr<CPdf> &pdf, std::string * filterName); /** Returns cobjects from given reference property. * @param refProp Reference property (must be pRef typed). @@ -1945,11 +1888,12 @@ boost::shared_ptr<CType> getCObjectFromR throw ElementBadTypeException(""); // gets reference value and dereferences indirect object - assert(refProp->getPdf()); + boost::shared_ptr<CPdf> pdf = refProp->getPdf().lock(); + assert(pdf); assert(hasValidRef(refProp)); IndiRef ref; IProperty::getSmartCObjectPtr<CRef>(refProp)->getValue(ref); - boost::shared_ptr<IProperty> indirect_ptr=refProp->getPdf()->getIndirectProperty(ref); + boost::shared_ptr<IProperty> indirect_ptr=pdf->getIndirectProperty(ref); if(indirect_ptr->getType() != CType::type) throw ElementBadTypeException(""); return IProperty::getSmartCObjectPtr<CType>(indirect_ptr); @@ -1966,19 +1910,18 @@ boost::shared_ptr<CType> getCObjectFromR * @return CType instance wrapped by shared_ptr smart pointer. */ template<typename CType> -boost::shared_ptr<CType> getCObjectFromRef(IndiRef ref, CPdf & pdf) +boost::shared_ptr<CType> getCObjectFromRef(IndiRef ref, boost::shared_ptr<CPdf> pdf) { // REMARK // This helper has to be here because of gcc template manipulation - // (cobjecthelpers.h can't include from this header file) - - boost::shared_ptr<IProperty> indirect_ptr=pdf.getIndirectProperty(ref); + // (cobjecthelpers.h can't include from this header file) + assert(pdf); + boost::shared_ptr<IProperty> indirect_ptr=pdf->getIndirectProperty(ref); if(indirect_ptr->getType() != CType::type) throw ElementBadTypeException(""); return IProperty::getSmartCObjectPtr<CType>(indirect_ptr); } - } // namespace utils } // namespace pdfobjects Index: src/kernel/iproperty.cc =================================================================== --- src/kernel/iproperty.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/iproperty.cc 2008-04-03 18:48:20.000000000 +0200 @@ -37,7 +37,7 @@ namespace pdfobjects { // // Constructor // -IProperty::IProperty (CPdf* _pdf) : mode(mdUnknown), pdf(_pdf), wantDispatch (true) +IProperty::IProperty (boost::weak_ptr<CPdf> _pdf) : mode(mdUnknown), pdf(_pdf), wantDispatch (true) { ref.num = ref.gen = 0; } @@ -45,7 +45,7 @@ IProperty::IProperty (CPdf* _pdf) : mode // // Constructor // -IProperty::IProperty (CPdf* _pdf, const IndiRef& rf) +IProperty::IProperty (boost::weak_ptr<CPdf> _pdf, const IndiRef& rf) : ref(rf), mode(mdUnknown), pdf(_pdf), wantDispatch (true) {} @@ -72,15 +72,16 @@ IProperty::clone () const // Set/Get pdf // void -IProperty::setPdf (CPdf* p) +IProperty::setPdf (boost::weak_ptr<CPdf> p) { pdf = p; } void IProperty::canChange () const { - if (pdf && wantDispatch) - pdf->canChange (); + boost::shared_ptr<CPdf> p = pdf.lock(); + if (p && wantDispatch) + p->canChange (); } // @@ -113,7 +114,7 @@ IProperty::dispatchChange () const }else { // Indicate to pdf that it should change this object - CPdf* pdf = IProperty::getPdf (); + boost::shared_ptr<CPdf> pdf = IProperty::getPdf ().lock (); assert (pdf); pdf->changeIndirectProperty (indiObj); } Index: src/kernel/iproperty.h =================================================================== --- src/kernel/iproperty.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/iproperty.h 2008-04-03 18:48:20.000000000 +0200 @@ -88,9 +88,9 @@ enum PropertyType * This object implements Observer interface which means we can observe changes * made to all cobjects. * - * REMARK: The association with CPdf is stored in pdf variable as CPdf* and not a smart pointer. This has a good reason - * namely cyclic references of smart pointers. - + * REMARK: The association with CPdf is stored in pdf variable as weak_ptr<CPdf>. + * Each access to this variable has to be checked with weak_ptr::lock method which + * transforms it to proper shared_ptr if the underlaying pointer is still valid. */ class IProperty : public IPropertyObserverSubject { @@ -99,7 +99,7 @@ class IProperty : public IPropertyObserv private: IndiRef ref; /**< Objects pdf identification and generation number. */ PropertyMode mode; /**< Mode of this property. */ - CPdf* pdf; /**< This object belongs to this pdf. */ + boost::weak_ptr<CPdf> pdf; /**< This object belongs to this pdf. */ bool wantDispatch;/**< If true changes are dispatched. */ // @@ -112,10 +112,10 @@ private: protected: /** Basic constructor. */ - IProperty (CPdf* _pdf = NULL); + IProperty (boost::weak_ptr<CPdf> _pdf = boost::shared_ptr<CPdf>()); /** Constructor. */ - IProperty (CPdf* _pdf, const IndiRef& rf); + IProperty (boost::weak_ptr<CPdf> _pdf, const IndiRef& rf); // @@ -153,13 +153,13 @@ public: * Set association with pdf. * @param p pdf that this object belongs to */ - virtual void setPdf (CPdf* p); + virtual void setPdf (boost::weak_ptr<CPdf> p); /** * Returns pdf in which this object resides. * @return Pdf that this object is associated with. */ - CPdf* getPdf () const {return pdf;} + boost::weak_ptr<CPdf> getPdf () const {return pdf;} /** * Checks if a property can be changed. @@ -305,8 +305,11 @@ public: * @param pdf Pdf isntance to check. * @return true if pdf is not NULL, false otherwise. */ -inline bool isPdfValid(CPdf* pdf) - { return (NULL !=pdf); } +inline bool isPdfValid(boost::weak_ptr<CPdf> pdf) +{ + boost::shared_ptr<CPdf> cpdf = pdf.lock(); + return (NULL != cpdf.get()); +} /** * Checks whether iproprety belongs to a valid pdf. @@ -315,7 +318,9 @@ inline bool isPdfValid(CPdf* pdf) * @return isPdfValid(ip-&getPdf()). */ inline bool hasValidPdf(const IProperty& ip) - { return isPdfValid(ip.getPdf()); } +{ + return isPdfValid(ip.getPdf()); +} /** \copydoc hasValidPdf */ template<typename T> inline bool hasValidPdf(T ip) Index: src/kernel/carray.cc =================================================================== --- src/kernel/carray.cc.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/carray.cc 2008-04-03 18:48:20.000000000 +0200 @@ -47,7 +47,7 @@ using namespace boost; // // Protected constructor // -CArray::CArray (CPdf& p, Object& o, const IndiRef& rf) : IProperty (&p,rf) +CArray::CArray (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf) : IProperty (p,rf) { // Build the tree from xpdf object utils::complexValueFromXpdfObj<pArray,Value&> (*this, o, value); @@ -104,7 +104,7 @@ CArray::getProperty (PropertyId id) cons // // void -CArray::setPdf (CPdf* pdf) +CArray::setPdf (boost::weak_ptr<CPdf> pdf) { // Set pdf to this object IProperty::setPdf (pdf); @@ -170,7 +170,7 @@ CArray::delProperty (PropertyId id) // Be sure - oldip->setPdf (NULL); + oldip->setPdf (boost::shared_ptr<CPdf>()); oldip->setIndiRef (IndiRef()); }else @@ -302,7 +302,7 @@ CArray::setProperty (PropertyId id, IPro } // Be sure - oldip->setPdf (NULL); + oldip->setPdf (boost::shared_ptr<CPdf>()); oldip->setIndiRef (IndiRef()); }else @@ -333,7 +333,7 @@ CArray::_makeXpdfObject () const // any bound PDF instance. Nevertheless NULL xref is ok for // Object hierarchy (see Object::fetch method) XRef *xref = NULL; - CPdf *pdf = getPdf(); + boost::shared_ptr<CPdf> pdf = getPdf().lock(); if(pdf) xref = pdf->getCXref(); arrayObj->initArray(xref); Index: src/kernel/carray.h =================================================================== --- src/kernel/carray.h.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/carray.h 2008-04-03 18:48:20.000000000 +0200 @@ -90,7 +90,7 @@ public: * @param o Xpdf object. * @param rf Indirect id and gen id. */ - CArray (CPdf& p, Object& o, const IndiRef& rf); + CArray (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf); /** * Constructor. @@ -195,7 +195,7 @@ public: * Set pdf to this object and its children. * @param pdf New pdf. */ - virtual void setPdf (CPdf* pdf); + virtual void setPdf (boost::weak_ptr<CPdf> pdf); /** * Set ref to this object and its children. Index: src/kernel/cdict.cc =================================================================== --- src/kernel/cdict.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cdict.cc 2008-04-03 18:48:20.000000000 +0200 @@ -46,7 +46,7 @@ using namespace boost; // // Protected constructor // -CDict::CDict (CPdf& p, Object& o, const IndiRef& rf) : IProperty (&p,rf) +CDict::CDict (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf) : IProperty (p,rf) { // Build the tree from xpdf object utils::complexValueFromXpdfObj<pDict,Value&> (*this, o, value); @@ -128,7 +128,7 @@ CDict::getProperty (PropertyId id) const // // void -CDict::setPdf (CPdf* pdf) +CDict::setPdf (boost::weak_ptr<CPdf> pdf) { // Set pdf to this object IProperty::setPdf (pdf); @@ -202,7 +202,7 @@ CDict::delProperty (PropertyId id) } // Be sure - oldip->setPdf (NULL); + oldip->setPdf (boost::shared_ptr<CPdf>()); oldip->setIndiRef (IndiRef()); }else @@ -332,7 +332,7 @@ CDict::setProperty (PropertyId id, IProp } // Be sure - oldIp->setPdf (NULL); + oldIp->setPdf (boost::shared_ptr<CPdf>()); oldIp->setIndiRef (IndiRef()); }else @@ -365,7 +365,7 @@ CDict::_makeXpdfObject () const // any bound PDF instance. Nevertheless NULL xref is ok for // Object hierarchy (see Object::fetch method) XRef *xref = NULL; - CPdf *pdf = getPdf(); + boost::shared_ptr<CPdf> pdf = getPdf().lock(); if(pdf) xref = pdf->getCXref(); dictObj->initDict(xref); @@ -419,7 +419,8 @@ void CDict::_setMode (shared_ptr<IProperty> ip, PropertyId id) const { configuration::ModeController* modecontroller = NULL; - if (hasValidPdf (this) && (NULL != (modecontroller=this->getPdf()->getModeController()))) + shared_ptr<CPdf> p = this->getPdf().lock(); + if ( p && (NULL != (modecontroller=p->getModeController()))) { assert (modecontroller); PropertyMode mode; Index: src/kernel/cdict.h =================================================================== --- src/kernel/cdict.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cdict.h 2008-04-03 18:48:20.000000000 +0200 @@ -96,7 +96,7 @@ public: * @param o Xpdf object. * @param rf Indirect id and gen id. */ - CDict (CPdf& p, Object& o, const IndiRef& rf); + CDict (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf); /** * Constructor. @@ -225,7 +225,7 @@ public: * Set pdf to this object and its children. * @param pdf New pdf. */ - virtual void setPdf (CPdf* pdf); + virtual void setPdf (boost::weak_ptr<CPdf> pdf); /** * Set ref to this object and its children. Index: src/kernel/cobject.cc =================================================================== --- src/kernel/cobject.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cobject.cc 2008-04-03 18:48:20.000000000 +0200 @@ -59,7 +59,7 @@ objHasParent (const IProperty& ip, boost if (!hasValidPdf (ip)) throw CObjInvalidOperation (); - CPdf* pdf = ip.getPdf (); + shared_ptr<CPdf> pdf = ip.getPdf ().lock (); IndiRef ref = ip.getIndiRef(); if ( &ip == (indiObj=pdf->getIndirectProperty(ref)).get() ) return false; Index: src/kernel/cobject2xpdf.cc =================================================================== --- src/kernel/cobject2xpdf.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cobject2xpdf.cc 2008-04-03 18:48:20.000000000 +0200 @@ -446,7 +446,7 @@ namespace { assert (0 <= array.arrayGetLength ()); utilsPrintDbg (debug::DBG_DBG, "xpdfArrayReader\tobjType = " << array.getTypeName() ); - CPdf* pdf = ip.getPdf (); + boost::shared_ptr<CPdf> pdf = ip.getPdf ().lock (); XpdfObject obj; int len = array.arrayGetLength (); @@ -460,7 +460,7 @@ namespace { if (isPdfValid(pdf)) { hasValidRef (ip); - cobj = shared_ptr<IProperty> (createObjFromXpdfObj (*pdf, *obj, ip.getIndiRef())); + cobj = shared_ptr<IProperty> (createObjFromXpdfObj (pdf, *obj, ip.getIndiRef())); }else { @@ -495,7 +495,7 @@ namespace { assert (0 <= dict.dictGetLength ()); utilsPrintDbg (debug::DBG_DBG, "xpdfDictReader\tobjType = " << dict.getTypeName() ); - CPdf* pdf = ip.getPdf (); + boost::shared_ptr<CPdf> pdf = ip.getPdf ().lock (); xpdf::XpdfObject obj; int len = dict.dictGetLength (); @@ -509,7 +509,7 @@ namespace { shared_ptr<IProperty> cobj; // Create CObject from it if (isPdfValid (pdf)) - cobj = shared_ptr<IProperty> (createObjFromXpdfObj (*pdf, *obj, ip.getIndiRef())); + cobj = shared_ptr<IProperty> (createObjFromXpdfObj (pdf, *obj, ip.getIndiRef())); else cobj = shared_ptr<IProperty> (createObjFromXpdfObj (*obj)); @@ -604,7 +604,7 @@ getStringFromXpdfStream (std::string& st // Creates CObject from xpdf object. // IProperty* -createObjFromXpdfObj (CPdf& pdf, Object& obj,const IndiRef& ref) +createObjFromXpdfObj (boost::shared_ptr<CPdf> pdf, Object& obj,const IndiRef& ref) { switch (obj.getType ()) { Index: src/kernel/cobjectsimple.h =================================================================== --- src/kernel/cobjectsimple.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cobjectsimple.h 2008-04-03 18:48:20.000000000 +0200 @@ -130,7 +130,7 @@ public: * @param o Xpdf object. * @param rf Indirect id and gen id. */ - CObjectSimple (CPdf& p, Object& o, const IndiRef& rf); + CObjectSimple (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf); /** * Constructor. @@ -420,7 +420,7 @@ makeStringPdfValid (GString * str) * * @return Pointer to newly created object. */ -IProperty* createObjFromXpdfObj (CPdf& pdf, ::Object& obj,const IndiRef& ref); +IProperty* createObjFromXpdfObj (boost::shared_ptr<CPdf> pdf, ::Object& obj,const IndiRef& ref); /** * Creates CObject* from xpdf object. Index: src/kernel/cobjectsimpleI.h =================================================================== --- src/kernel/cobjectsimpleI.h.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/cobjectsimpleI.h 2008-04-03 18:48:20.000000000 +0200 @@ -42,7 +42,7 @@ namespace pdfobjects { // Protected constructor, called when we have parsed an object // template<PropertyType Tp> -CObjectSimple<Tp>::CObjectSimple (CPdf& p, Object& o, const IndiRef& rf) : IProperty (&p,rf), value(Value()) +CObjectSimple<Tp>::CObjectSimple (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf) : IProperty (p,rf), value(Value()) { //kernelPrintDbg (debug::DBG_DBG,"CObjectSimple <" << debug::getStringType<Tp>() << ">(p,o,rf) constructor."); Index: src/kernel/cstream.cc =================================================================== --- src/kernel/cstream.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cstream.cc 2008-04-03 18:48:20.000000000 +0200 @@ -46,7 +46,7 @@ using namespace utils; // // // -CStream::CStream (CPdf& p, ::Object& o, const IndiRef& rf) : IProperty (&p,rf), parser (NULL), tmpObj (NULL) +CStream::CStream (boost::weak_ptr<CPdf> p, ::Object& o, const IndiRef& rf) : IProperty (p,rf), parser (NULL), tmpObj (NULL) { kernelPrintDbg (debug::DBG_DBG,""); // Make sure it is a stream @@ -63,7 +63,7 @@ CStream::CStream (CPdf& p, ::Object& o, objDict.free (); // Set pdf and ref - dictionary.setPdf (&p); + dictionary.setPdf (p); dictionary.setIndiRef (rf); // Save the contents of the container @@ -161,7 +161,7 @@ CStream::doClone () const // // void -CStream::setPdf (CPdf* pdf) +CStream::setPdf (boost::weak_ptr<CPdf> pdf) { // Set pdf to this object and dictionary it contains IProperty::setPdf (pdf); @@ -408,7 +408,10 @@ CStream::open () throw CObjInvalidOperation (); } - ::XRef* xref = (NULL != this->getPdf ()) ? this->getPdf ()->getCXref() : NULL; + ::XRef* xref = NULL; + boost::shared_ptr<CPdf> p = this->getPdf ().lock (); + if (p) + xref = p->getCXref(); // Create xpdf object from current stream and parse it tmpObj = _makeXpdfObject (); parser = new ::Parser (xref, new ::Lexer(xref, tmpObj), gFalse); Index: src/kernel/cstream.h =================================================================== --- src/kernel/cstream.h.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/cstream.h 2008-04-03 18:48:20.000000000 +0200 @@ -114,7 +114,7 @@ public: * @param o Xpdf object. * @param rf Indirect id and gen id. */ - CStream (CPdf& p, Object& o, const IndiRef& rf); + CStream (boost::weak_ptr<CPdf> p, Object& o, const IndiRef& rf); /** * Constructor. Stream will not be associated with a pdf. @@ -284,7 +284,7 @@ public: * Set pdf to itself and also to all children. * @param pdf New pdf. */ - virtual void setPdf (CPdf* pdf); + virtual void setPdf (boost::weak_ptr<CPdf> pdf); /** * Set ref to itself and also to all children. Index: src/kernel/ccontentstream.cc =================================================================== --- src/kernel/ccontentstream.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/ccontentstream.cc 2008-04-03 18:48:20.000000000 +0200 @@ -68,7 +68,7 @@ namespace { */ void opsSetPdfRefCs (shared_ptr<PdfOperator> first, - CPdf& pdf, + boost::weak_ptr<CPdf> pdf, IndiRef rf, CContentStream& cs, boost::shared_ptr<IPropertyObserver> observer) @@ -85,7 +85,7 @@ namespace { // -- cstream won't get notified by its children, not needed // if (0 < it.getCurrent()->getParametersCount()) - it.getCurrent()->init_operands (observer, &pdf, &rf); + it.getCurrent()->init_operands (observer, pdf, &rf); it = it.next (); } @@ -430,11 +430,11 @@ namespace { if (!hasValidPdf (*it) || !hasValidRef (*it)) throw CObjInvalidObject (); } - CPdf* pdf = streams.front()->getPdf (); - assert (pdf); + weak_ptr<CPdf> pdf = streams.front()->getPdf (); + assert (pdf.lock()); IndiRef rf = streams.front()->getIndiRef (); - assert (!streams.empty()); + assert (!streams.empty()); CStreamsXpdfReader<CContentStream::CStreams> streamreader (streams); streamreader.open (); @@ -535,7 +535,7 @@ namespace { assert (observer); // Set pdf ref and cs if (!operators.empty()) - opsSetPdfRefCs (operators.front(), *pdf, rf, cs, observer); + opsSetPdfRefCs (operators.front(), pdf, rf, cs, observer); } @@ -898,10 +898,10 @@ CContentStream::insertOperator (Operator // Set correct IndiRef, CPdf and cs to inserted operator assert (hasValidRef (cstreams.front())); assert (hasValidPdf (cstreams.front())); - CPdf* pdf = cstreams.front()->getPdf(); - assert (pdf); + weak_ptr<CPdf> pdf = cstreams.front()->getPdf(); + assert (pdf.lock()); IndiRef rf = cstreams.front()->getIndiRef (); - opsSetPdfRefCs (newOper, *pdf, rf, *this, operandobserver); + opsSetPdfRefCs (newOper, pdf, rf, *this, operandobserver); // // Insert into operators or composite @@ -979,17 +979,17 @@ CContentStream::frontInsertOperator (boo // Check whether we can make the change cstreams.front()->canChange(); IndiRef rf = cstreams.front()->getIndiRef (); - CPdf* pdf = cstreams.front()->getPdf(); - assert (pdf); + weak_ptr<CPdf> pdf = cstreams.front()->getPdf(); + assert (pdf.lock()); // set accordingly - opsSetPdfRefCs (newoper, *pdf, rf, *this, operandobserver); + opsSetPdfRefCs (newoper, pdf, rf, *this, operandobserver); if (operators.empty ()) { // Insert into empty contentstream operators.push_back (newoper); }else { // Insert into - opsSetPdfRefCs (newoper, *pdf, rf, *this, operandobserver); + opsSetPdfRefCs (newoper, pdf, rf, *this, operandobserver); shared_ptr<PdfOperator> secondoper = operators.front(); operators.push_front (newoper); @@ -1034,10 +1034,10 @@ CContentStream::replaceOperator (Operato // Set correct IndiRef, CPdf and cs to inserted operator assert (hasValidRef (cstreams.front())); assert (hasValidPdf (cstreams.front())); - CPdf* pdf = cstreams.front()->getPdf(); - assert (pdf); + weak_ptr<CPdf> pdf = cstreams.front()->getPdf(); + assert (pdf.lock()); IndiRef rf = cstreams.front()->getIndiRef (); - opsSetPdfRefCs (newOper, *pdf, rf, *this, operandobserver); + opsSetPdfRefCs (newOper, pdf, rf, *this, operandobserver); // // Replace in operators or composite Index: src/kernel/cobjecthelpers.cc =================================================================== --- src/kernel/cobjecthelpers.cc.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/cobjecthelpers.cc 2008-04-03 18:48:20.000000000 +0200 @@ -125,7 +125,9 @@ boost::shared_ptr<CDict> getDictFromRef( // gets reference value and dereferences indirect object IndiRef ref; IProperty::getSmartCObjectPtr<CRef>(refProp)->getValue(ref); - boost::shared_ptr<IProperty> indirect_ptr=refProp->getPdf()->getIndirectProperty(ref); + shared_ptr<CPdf> pdf = refProp->getPdf().lock(); + assert(pdf); + boost::shared_ptr<IProperty> indirect_ptr=pdf->getIndirectProperty(ref); if(indirect_ptr->getType() != pDict) throw ElementBadTypeException(""); return IProperty::getSmartCObjectPtr<CDict>(indirect_ptr); @@ -235,7 +237,9 @@ getReferencedObject (boost::shared_ptr<I IndiRef ref; IProperty::getSmartCObjectPtr<CRef>(ip)->getValue(ref); - return ip->getPdf()->getIndirectProperty (ref); + shared_ptr<CPdf> pdf = ip->getPdf().lock(); + assert(pdf); + return pdf->getIndirectProperty (ref); }else return ip; @@ -320,7 +324,12 @@ using namespace boost; // ::XRef* getXRef (shared_ptr<IProperty> ip) - { return (ip->getPdf() == NULL) ? NULL : ip->getPdf()->getCXref(); } +{ + shared_ptr<CPdf> pdf = ip->getPdf().lock(); + if(!pdf) + return NULL; + return pdf->getCXref(); +} Index: src/kernel/pdfoperators.cc =================================================================== --- src/kernel/pdfoperators.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/pdfoperators.cc 2008-04-03 18:48:20.000000000 +0200 @@ -144,7 +144,7 @@ SimpleGenericOperator::clone () void SimpleGenericOperator::init_operands (shared_ptr<observer::IObserver<IProperty> > observer, - CPdf* pdf, + boost::weak_ptr<CPdf> pdf, IndiRef* rf) { // store observer @@ -154,7 +154,7 @@ SimpleGenericOperator::init_operands (sh { if (hasValidPdf(*oper)) { // We do not support adding operators from another stream - if ( ((*oper)->getPdf() != pdf) || !((*oper)->getIndiRef() == *rf) ) + if ( ((*oper)->getPdf().lock() != pdf.lock()) || !((*oper)->getIndiRef() == *rf) ) { kernelPrintDbg (debug::DBG_CRIT, "Pdf or indiref do not match: want " << *rf << " op has" <<(*oper)->getIndiRef()); throw CObjInvalidObject (); Index: src/kernel/pdfoperators.h =================================================================== --- src/kernel/pdfoperators.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/pdfoperators.h 2008-04-03 18:48:20.000000000 +0200 @@ -100,7 +100,7 @@ protected: // Observer interface // public: - void init_operands (boost::shared_ptr<observer::IObserver<IProperty> > observer, CPdf* pdf, IndiRef* rf); + void init_operands (boost::shared_ptr<observer::IObserver<IProperty> > observer, boost::weak_ptr<CPdf> pdf, IndiRef* rf); // // Destructor Index: src/kernel/pdfoperatorsbase.cc =================================================================== --- src/kernel/pdfoperatorsbase.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/pdfoperatorsbase.cc 2008-04-03 18:48:20.000000000 +0200 @@ -189,7 +189,7 @@ CompositePdfOperator::getStringRepresent } void -CompositePdfOperator::init_operands (shared_ptr<observer::IObserver<IProperty> > observer, CPdf* pdf, IndiRef* rf) +CompositePdfOperator::init_operands (shared_ptr<observer::IObserver<IProperty> > observer, boost::weak_ptr<CPdf> pdf, IndiRef* rf) { for (PdfOperators::iterator it = _children.begin (); it != _children.end(); ++it) (*it)->init_operands (observer, pdf, rf); Index: src/kernel/pdfoperatorsbase.h =================================================================== --- src/kernel/pdfoperatorsbase.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/pdfoperatorsbase.h 2008-04-03 18:48:20.000000000 +0200 @@ -331,7 +331,7 @@ public: /** * Init operands and store observer for later unregistering. */ - virtual void init_operands (boost::shared_ptr<observer::IObserver<IProperty> >, CPdf*, IndiRef*) = 0; + virtual void init_operands (boost::shared_ptr<observer::IObserver<IProperty> >, boost::weak_ptr<CPdf>, IndiRef*) = 0; }; // class PdfOperator @@ -386,7 +386,7 @@ public: virtual void getParameters (Operands&) const {} virtual void getStringRepresentation (std::string& str) const; virtual void getOperatorName (std::string& first) const = 0; - virtual void init_operands (boost::shared_ptr<observer::IObserver<IProperty> > observer, CPdf* pdf, IndiRef* rf); + virtual void init_operands (boost::shared_ptr<observer::IObserver<IProperty> > observer, boost::weak_ptr<CPdf> pdf, IndiRef* rf); // // Clone interface Index: src/kernel/cinlineimage.cc =================================================================== --- src/kernel/cinlineimage.cc.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/cinlineimage.cc 2008-04-03 18:48:20.000000000 +0200 @@ -100,7 +100,7 @@ CInlineImage::CInlineImage (::Object& oD // // // -CInlineImage::CInlineImage (CPdf& p, ::Object& oDict, const CStream::Buffer& buf, const IndiRef& rf) : CStream () +CInlineImage::CInlineImage (boost::weak_ptr<CPdf> p, ::Object& oDict, const CStream::Buffer& buf, const IndiRef& rf) : CStream () { kernelPrintDbg (debug::DBG_DBG, ""); assert (objDict == oDict.getType()); @@ -110,7 +110,7 @@ CInlineImage::CInlineImage (CPdf& p, ::O assert (0 < this->dictionary.getPropertyCount ()); // Set pdf and ref - setPdf (&p); + setPdf (p); setIndiRef (rf); // Set buffer, do not use setRawBuffer because CStream would be ... copied Index: src/kernel/cinlineimage.h =================================================================== --- src/kernel/cinlineimage.h.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cinlineimage.h 2008-04-03 18:48:20.000000000 +0200 @@ -75,7 +75,7 @@ public: * @param buffer Raw stream data. * @param rf Indirect reference numbers. */ - CInlineImage (CPdf& p, ::Object& objDict, const CStream::Buffer& buffer, const IndiRef& rf); + CInlineImage (boost::weak_ptr<CPdf> p, ::Object& objDict, const CStream::Buffer& buffer, const IndiRef& rf); /** Constructor. It will not be associated with a pdf. */ CInlineImage () : CStream(false) {} Index: src/kernel/cpage.cc =================================================================== --- src/kernel/cpage.cc.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/kernel/cpage.cc 2008-04-03 18:48:20.000000000 +0200 @@ -114,7 +114,8 @@ CPage::~CPage () invalidate (); // indicate we are ending - _dict->setPdf (NULL); + // FIXME remove - added as workaround for 233 + //_dict->setPdf (boost::shared_ptr<CPdf>()); // inform modules for (Modules::iterator it = _modules.begin(); it != _modules.end(); ++it) @@ -251,7 +252,7 @@ size_t CPage::getPagePosition () const { if (hasValidPdf (_dict)) - return _dict->getPdf()->getPagePosition (shared_ptr<CPage>(const_cast<CPage*>(this),EmptyDeallocator<CPage> ())); + return _dict->getPdf().lock()->getPagePosition (shared_ptr<CPage>(const_cast<CPage*>(this),EmptyDeallocator<CPage> ())); throw CObjInvalidOperation (); } Index: src/kernel/cpageannots.cc =================================================================== --- src/kernel/cpageannots.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cpageannots.cc 2008-04-03 18:48:20.000000000 +0200 @@ -352,12 +352,12 @@ CPageAnnots::consolidate(boost::shared_p void CPageAnnots::add(boost::shared_ptr<CAnnotation> annot) { - kernelPrintDbg(debug::DBG_DBG, ""); + kernelPrintDbg(debug::DBG_DBG, ""); // gets pdf of this annotation - it is valid - CPdf* pdf=_page->getDictionary()->getPdf(); - if (!pdf) - throw CObjInvalidObject (); + boost::shared_ptr<CPdf> pdf=_page->getDictionary()->getPdf().lock(); + if (!pdf) + throw CObjInvalidObject (); // gets Annots array from page dictionary. If no found, creates it. If bad // typed, throws an exception Index: src/kernel/cpagecontents.cc =================================================================== --- src/kernel/cpagecontents.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cpagecontents.cc 2008-04-03 18:48:20.000000000 +0200 @@ -156,7 +156,7 @@ namespace { */ template<typename Container> boost::shared_ptr<CStream> - createStreamFromObjects (const Container& cont, CPdf& pdf) + createStreamFromObjects (const Container& cont, boost::weak_ptr<CPdf> pdf) { // Create stream with one default property Length shared_ptr<CStream> newstr (new CStream()); @@ -185,8 +185,10 @@ namespace { newstr->setBuffer (str); // Set ref and indiref reserve free indiref for the new object - IndiRef newref = pdf.addIndirectProperty (newstr); - newstr = IProperty::getSmartCObjectPtr<CStream> (pdf.getIndirectProperty (newref)); + boost::shared_ptr<CPdf> p = pdf.lock(); + assert(p); + IndiRef newref = p->addIndirectProperty (newstr); + newstr = IProperty::getSmartCObjectPtr<CStream> (p->getIndirectProperty (newref)); assert (newstr); return newstr; @@ -258,12 +260,10 @@ void CPageContents::addToFront (const Container& cont) { // Create cstream from container of pdf operators - CPdf* pdf = _dict->getPdf(); - assert (pdf); - shared_ptr<CStream> stream = createStreamFromObjects (cont, *pdf); - assert (hasValidRef (stream)); assert (hasValidPdf (stream)); - if (!hasValidPdf(stream) || !hasValidPdf(stream)) - throw CObjInvalidObject (); + shared_ptr<CStream> stream = createStreamFromObjects (cont, _dict->getPdf()); + assert (hasValidRef (stream)); assert (hasValidPdf (stream)); + if (!hasValidPdf(stream) || !hasValidPdf(stream)) + throw CObjInvalidObject (); // Change the contents entry CRef rf (stream->getIndiRef()); @@ -299,13 +299,12 @@ void CPageContents::addToBack (const Container& cont) { // Create cstream from container of pdf operators - CPdf* pdf = _dict->getPdf(); - if (!pdf) - throw CObjInvalidObject (); - shared_ptr<CStream> stream = createStreamFromObjects (cont, *pdf); - assert (hasValidRef (stream)); assert (hasValidPdf (stream)); - if (!hasValidPdf(stream) || !hasValidPdf(stream)) - throw CObjInvalidObject (); + if (!hasValidPdf(_dict)) + throw CObjInvalidObject (); + shared_ptr<CStream> stream = createStreamFromObjects (cont, _dict->getPdf()); + assert (hasValidRef (stream)); assert (hasValidPdf (stream)); + if (!hasValidPdf(stream) || !hasValidPdf(stream)) + throw CObjInvalidObject (); // Change the contents entry CRef rf (stream->getIndiRef()); @@ -337,10 +336,10 @@ template void CPageContents::addToBack<d void CPageContents::remove (size_t csnum) { - if (!_dict->getPdf()) - throw CObjInvalidObject (); - if (csnum >= _ccs.size()) - throw OutOfRange (); + if (!hasValidPdf(_dict)) + throw CObjInvalidObject (); + if (csnum >= _ccs.size()) + throw OutOfRange (); // Change the contents entry remove (_ccs[csnum]); Index: src/kernel/cpagedisplay.cc =================================================================== --- src/kernel/cpagedisplay.cc.orig 2008-04-03 18:12:57.000000000 +0200 +++ src/kernel/cpagedisplay.cc 2008-04-03 18:48:20.000000000 +0200 @@ -87,10 +87,11 @@ CPageDisplay::displayPage (::OutputDev& int x, int y, int w, int h) { // Get xref - XRef* xref = pagedict->getPdf()->getCXref (); - assert (NULL != xref); - if (!(pagedict)) - throw XpdfInvalidObject (); + shared_ptr<CPdf> pdf = pagedict->getPdf().lock(); + XRef* xref = (pdf)?pdf->getCXref ():NULL; + assert (NULL != xref); + if (!(pagedict)) + throw XpdfInvalidObject (); // // Create xpdf object representing CPage @@ -150,11 +151,12 @@ CPageDisplay::createXpdfDisplayParams (s CPageAttributes::fillInherited (_page->getDictionary(),atr); // Start the resource stack - XRef* xref = _page->getDictionary()->getPdf()->getCXref(); - assert (xref); + shared_ptr<CPdf> pdf = _page->getDictionary()->getPdf().lock(); + XRef* xref = (pdf)?pdf->getCXref():NULL; + assert (xref); Object* obj = atr._resources->_makeXpdfObject (); - assert (obj); - assert (objDict == obj->getType()); + assert (obj); + assert (objDict == obj->getType()); res = shared_ptr<GfxResources> (new GfxResources(xref, obj->getDict(), NULL)); xpdf::freeXpdfObject (obj); Index: src/gui/additemdialog.cc =================================================================== --- src/gui/additemdialog.cc.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/gui/additemdialog.cc 2008-04-03 18:48:20.000000000 +0200 @@ -132,7 +132,7 @@ void AddItemDialog::buttonSelected(int i */ void AddItemDialog::setItem(boost::shared_ptr<IProperty> it) { item=it; - pdf=it->getPdf(); + pdf=it->getPdf().lock(); //We must set PDF to property RefProperty* refProp=dynamic_cast<RefProperty*>(props[5]); Index: src/gui/additemdialog.h =================================================================== --- src/gui/additemdialog.h.orig 2008-04-03 18:12:56.000000000 +0200 +++ src/gui/additemdialog.h 2008-04-03 18:48:20.000000000 +0200 @@ -100,7 +100,7 @@ private: /** Settings used to save dialog position (dict/array) - this is useful, as these can have different sizes */ QString settingName; /** Pdf document (for validating reference) */ - CPdf* pdf; + boost::shared_ptr<CPdf> pdf; /** Radiobutton for inserting at arbitrary position in array */ QRadioButton *posNum; /** Radiobutton for appending at end of array */ Index: src/gui/pdfeditwindow.cc =================================================================== --- src/gui/pdfeditwindow.cc.orig 2008-04-03 18:48:18.000000000 +0200 +++ src/gui/pdfeditwindow.cc 2008-04-03 18:48:20.000000000 +0200 @@ -778,7 +778,7 @@ void PdfEditWindow::setTitle(int revisio if (revision) revisionInfo=QString(" - ")+tr("viewing revision")+" "+QString::number(revision); QStringList docFlags; if (document->isLinearized()) docFlags+=tr("Linearized PDF"); - if (pdfobjects::utils::isEncrypted(*document,NULL)) docFlags+=tr("Encrypted"); + if (pdfobjects::utils::isEncrypted(document,NULL)) docFlags+=tr("Encrypted"); QString docInfo=""; if (docFlags.count()) { docInfo=" ( "+docFlags.join(", ")+" )"; Index: src/gui/pdfutil.cc =================================================================== --- src/gui/pdfutil.cc.orig 2008-04-03 18:48:18.000000000 +0200 +++ src/gui/pdfutil.cc 2008-04-03 18:48:20.000000000 +0200 @@ -219,7 +219,8 @@ IndiRef getRef(boost::shared_ptr<IProper @param ref Indirect reference to check @return true if given reference target exists in given pdf, false otherwise */ -bool isRefValid(CPdf *pdf,IndiRef ref) { +bool isRefValid(boost::shared_ptr<CPdf> pdf,IndiRef ref) { + assert(pdf); CXref *cxref=pdf->getCXref(); Ref _val;//TODO: why there is no knowsRef(IndiRef) ? _val.num=ref.num; @@ -259,7 +260,7 @@ bool isSimple(IProperty* prop) { boost::shared_ptr<IProperty> dereference(boost::shared_ptr<IProperty> obj) { if (!obj.get()) return obj; //Empty pointer if (obj->getType()!=pRef) return obj; //Not a reference - CPdf* pdf=obj->getPdf(); + boost::shared_ptr<CPdf> pdf=obj->getPdf().lock(); // TODO Is this really ok? Shouldn't we create rather CNull here? if (!pdf) return boost::shared_ptr<IProperty>(); //Property does not belong to document -> cannot dereference IndiRef ref; Index: src/gui/pdfutil.h =================================================================== --- src/gui/pdfutil.h.orig 2008-04-03 18:48:18.000000000 +0200 +++ src/gui/pdfutil.h 2008-04-03 18:48:20.000000000 +0200 @@ -47,7 +47,7 @@ QString getTypeName(IProperty *obj); QString getTypeName(boost::shared_ptr<IProperty> obj); IndiRef getRef(IProperty *ref); IndiRef getRef(boost::shared_ptr<IProperty> ref); -bool isRefValid(CPdf *pdf, IndiRef ref); +bool isRefValid(boost::shared_ptr<CPdf> pdf, IndiRef ref); bool isSimple(IProperty* prop); bool isSimple(boost::shared_ptr<IProperty> prop); boost::shared_ptr<IProperty> dereference(boost::shared_ptr<IProperty> obj); Index: src/gui/refproperty.cc =========... [truncated message content] |