#include <cxref.h>
Classes | |
| struct | ObjectEntry |
Public Member Functions | |
| CXref (BaseStream *stream) | |
| virtual | ~CXref () |
| virtual void | setCredentials (const char *ownerPasswd, const char *userPasswd) |
| bool | getNeedCredentials () const |
| virtual RefState | knowsRef (const ::Ref &ref) const |
| virtual RefState | knowsRef (const IndiRef &ref) const |
| virtual bool | typeSafe (::Object *obj1,::Object *obj2) |
| virtual ::Object * | getTrailerEntry (char *name) |
| virtual ::Object * | getDocInfo (::Object *obj) |
| virtual ::Object * | getDocInfoNF (::Object *obj) |
| virtual int | getNumObjects () const |
| virtual ::Object * | fetch (int num, int gen,::Object *obj) const |
Protected Types | |
| typedef ObjectStorage< const ::Ref, ObjectEntry *, xpdf::RefComparator > | ChangedStorage |
| typedef ObjectStorage< const ::Ref, RefState, xpdf::RefComparator > | RefStorage |
Protected Member Functions | |
| CXref () | |
| ::Object * | changeObject (::Ref ref,::Object *instance) |
| virtual const Object * | getTrailerDict () const |
| ::Object * | changeTrailer (const char *name,::Object *value) |
| void | reopen (size_t xrefOff, bool dropChanges=true) |
| virtual ::Ref | reserveRef () |
| virtual ::Object * | createObject (::ObjType type,::Ref *ref) |
| void | cleanUp () |
| bool | checkEncryptedContent () |
| void | enableInternalFetch () |
| void | disableInternalFetch () |
Protected Attributes | |
| ChangedStorage | changedStorage |
| RefStorage | newStorage |
| boost::shared_ptr< Object > | currTrailer |
Private Member Functions | |
| void | init () |
Private Attributes | |
| bool | needs_credentials |
| bool | internal_fetch |
Adapter for xpdf XRef class.
This class has responsibility to transparently (same way as XRef do) provide objects synchronized with changes.
Class works in three layers:
Each request to XRef inherited interface, which manipulates with object which can change, asks Maintaining layer at first. If it is not able to to get required object, xpdf layer is used (delegates to super type).
Methods which produces changes are protected to prevent changing in gui, if kernel wants to make changes, it should use XrefWriter subclass which delegates functionality to inherited protected methods and adds some checking.
We have prepared XRef implementation to be virtual, so there is no problem to use CXref instance as XRef in rest of xpdf code. Initialization of xref from file (respectively from basestream) is done only by xpdf layer (if no changes are done to the file - Maintaining layer doesn't contain any additional information than after CXref initialization).
Because, in fact, all object which can be changed (we are meaning change value inside Object instance) has to be indirect Object, obj and gen number are used as identificators, when objects are stored to the ChangedStorage. So when someone wants to change object value using changeObject method, he has to suply also obj and gen numbers. Only one exception in pdf format is trailer, which is not indirect object and this can be changed using changeTrailer method. This method can change entries in trailer. If user whants to change indirect object values stored in trailer, it can be done in standard way as any other objects.
Objects returned by this interface are always deep copies of original object stored inside and changes made to them are not visible through this interface until changeObject or changeTrailer is called.
typedef ObjectStorage<const ::Ref, ObjectEntry*, xpdf::RefComparator> pdfobjects::CXref::ChangedStorage [protected] |
typedef ObjectStorage<const ::Ref, RefState, xpdf::RefComparator> pdfobjects::CXref::RefStorage [protected] |
| pdfobjects::CXref::CXref | ( | ) | [inline, protected] |
Empty constructor.
This constructor is protected to prevent uninitialized instances. We need at least to specify stream with data.
| CXref::CXref | ( | BaseStream * | stream | ) |
Initialize constructor.
| stream | Stream with file data. |
Delegates to XRef constructor with same parameter.
Given stream is always deallocated in this class. Caller should never (even if an exception is thrown) deallocate it.
| MalformedFormatExeption | if XRef creation fails (instance is unusable in such situation). | |
| PDFedit_devException | if pdfedit-core-dev is not initialized. |
References init().
| CXref::~CXref | ( | ) | [virtual] |
Initialize constructor with cache.
| stream | Stream with file data. | |
| c | Cache instance. |
Delegates to XRef constructor with the stream parameter and sets cache instance.
| MalformedFormatExeption | if XRef creation fails (instance is unusable in such situation). Destructor. |
Calls cleanUp for all internals deallocation and deletes stream.
References cleanUp(), debug::DBG_DBG, and kernelPrintDbg.
| Object * CXref::changeObject | ( | ::Ref | ref, | |
| ::Object * | instance | |||
| ) | [protected] |
Registers change in given object addressable through given reference.
| ref | Object reference identificator. | |
| instance | Instance of object value (must be direct value, not indirect reference). |
Discards object from cache and stores given to the changedStorage. Method should be called each time when object has changed its value. Object value is copied not use as it is (creates deep copy by clone method).
If object with same reference already was in changedStorage, this is returned to enable history handling (and also to deallocate it). 0 return value means first change of object.
If given reference is in newStorage, value is set to true to signalize that value has been changed after object has been created.
Note that this function doesn't perform any value ckecking.
| NotImplementedException | if object cloning fails. |
References changedStorage, check_need_credentials, ObjectStorage< K, V, Comp >::contains(), debug::DBG_DBG, debug::DBG_ERR, ObjectStorage< K, V, Comp >::get(), kernelPrintDbg, newStorage, pdfobjects::CXref::ObjectEntry::object, and ObjectStorage< K, V, Comp >::put().
| Object * CXref::changeTrailer | ( | const char * | name, | |
| ::Object * | value | |||
| ) | [protected] |
Changes entry in trailer dictionary.
| name | Name of the value. | |
| value | Value to be set. |
Makes changes to the trailer dictionary. If given value is indirect reference, it must be known.
NOTE: doesn't perform any value checking.
| NotImplementedException | if object cloning fails. |
Reimplemented in pdfobjects::XRefWriter.
References check_need_credentials, currTrailer, debug::DBG_DBG, debug::DBG_ERR, pdfobjects::XPdfObjectFactory::getInstance(), getTrailerDict(), and kernelPrintDbg.
| bool CXref::checkEncryptedContent | ( | ) | [protected] |
Checks whether document is encrypted and if so, sets needs_credentials and encrypted fields to true.
References disableInternalFetch(), enableInternalFetch(), pdfobjects::XPdfObjectFactory::getInstance(), getTrailerDict(), and needs_credentials.
| void CXref::cleanUp | ( | ) | [protected] |
Deallocates all internal structures.
Cleanes up chnagedStorage and deallocates all its entries.
This method is responsible for deallocation of all internal structures specific for CXref.
References ObjectStorage< K, V, Comp >::begin(), changedStorage, ObjectStorage< K, V, Comp >::clear(), currTrailer, debug::DBG_DBG, debug::DBG_ERR, ObjectStorage< K, V, Comp >::end(), xpdf::freeXpdfObject(), kernelPrintDbg, newStorage, pdfobjects::CXref::ObjectEntry::object, and ObjectStorage< K, V, Comp >::size().
| Object * CXref::createObject | ( | ::ObjType | type, | |
| ::Ref * | ref | |||
| ) | [protected] |
Creates new xpdf indirect object.
| type | Type of the object. | |
| ref | Structure where to put object num and gen (if null, nothing is set). |
New reference is registered using reserveRef method. This is just wrapper method to reserveRef with object initialization capability.
Implementation will initialize Object with type and value depending on type:
To change value of the object, use init{Type} method then call change method to register change and makes object visible by fetch method.
Returned object has to be deallocated by Object::free and gfree methods (first one for value deallocation and second for Object instance itself) or by pdfobjects::xpdf::freeXpdfObject method.
Reimplemented in pdfobjects::XRefWriter.
References debug::DBG_DBG, debug::DBG_INFO, pdfobjects::XPdfObjectFactory::getInstance(), kernelPrintDbg, and reserveRef().
| void pdfobjects::CXref::disableInternalFetch | ( | ) | [inline, protected] |
Disables internal fetching.
References internal_fetch.
Referenced by checkEncryptedContent(), setCredentials(), and pdfobjects::XRefWriter::XRefWriter().
| void pdfobjects::CXref::enableInternalFetch | ( | ) | [inline, protected] |
Enables internal fetching. This implies that fetch method is used for internal purposes, thus some checks are not performed (e.g. whether we have credentials for encrypted document).
This method should be called before fetch method and disableInternalFetch should be called after we are done.
References internal_fetch.
Referenced by checkEncryptedContent(), setCredentials(), and pdfobjects::XRefWriter::XRefWriter().
| Object * CXref::fetch | ( | int | num, | |
| int | gen, | |||
| ::Object * | obj | |||
| ) | const |
Fetches object.
| num | Object number. | |
| gen | Object generation. | |
| obj | Object where to store content. |
Try to find object in changedStorage and if not found, delegates to original implementation.
NOTE: Returned value is deepCopy of object and changes made to object don't affect internally maintained values (e.g. it can and should be deallocated by caller). To register a change use change method.
This method provides transparent access to changed objects throught XRef (xpdf class) interface.
Unless internal_fetch is set (by enableInternalFetch method), checks needs_credentials and throws PermissionException if flags is set.
| NotImplementedException | if object cloning fails. | |
| PermissionException | if we don't have credentials for encrypted document. |
Reimplemented in pdfobjects::XRefWriter.
References changedStorage, check_need_credentials, debug::DBG_CRIT, debug::DBG_DBG, debug::DBG_ERR, ObjectStorage< K, V, Comp >::get(), pdfobjects::XPdfObjectFactory::getInstance(), internal_fetch, kernelPrintDbg, and pdfobjects::CXref::ObjectEntry::object.
Referenced by pdfobjects::utils::Flattener::fillObjectList(), pdfobjects::utils::Delinearizator::fillObjectList(), and typeSafe().
| Object * CXref::getDocInfo | ( | ::Object * | obj | ) |
References debug::DBG_DBG, debug::DBG_ERR, pdfobjects::XPdfObjectFactory::getInstance(), and kernelPrintDbg.
| Object * CXref::getDocInfoNF | ( | ::Object * | obj | ) |
References debug::DBG_DBG, debug::DBG_ERR, pdfobjects::XPdfObjectFactory::getInstance(), and kernelPrintDbg.
| bool pdfobjects::CXref::getNeedCredentials | ( | ) | const [inline] |
Returns true if setCredentials method is required.
References needs_credentials.
Referenced by pdfobjects::CPdf::needsCredentials(), and pdfobjects::utils::PdfDocumentWriter::writeDocument().
| int CXref::getNumObjects | ( | ) | const [virtual] |
Returns number of indirect objects.
Delegates to XRef::getNumObjects and adds also number of all newly inserted (and initialized) objects.
Reimplemented in pdfobjects::XRefWriter.
References ObjectStorage< K, V, Comp >::begin(), debug::DBG_DBG, ObjectStorage< K, V, Comp >::end(), kernelPrintDbg, and newStorage.
Referenced by reserveRef().
| virtual const Object* pdfobjects::CXref::getTrailerDict | ( | ) | const [inline, protected, virtual] |
Overrides XRef::getTrailerDict to force changed trailer if there are some changes otherwise delegate to XRef::getTrailerDict. Never deallocate returned object.
Reimplemented in pdfobjects::XRefWriter.
References currTrailer.
Referenced by changeTrailer(), checkEncryptedContent(), getTrailerEntry(), pdfobjects::utils::Flattener::initReachableObjects(), and pdfobjects::utils::PdfDocumentWriter::writeDocument().
| Object * CXref::getTrailerEntry | ( | char * | name | ) |
Gets value associated with name in trailer.
| name | Name of the entry. |
If value is indirect reference (according specification almost all compound entries), reference is returned, so normal xref interface can be used to ask for value. If no value with given name can be found, objNull type object is returned.
Changes made to returned object doesn't affect trailer entry with given name.
References debug::DBG_DBG, debug::DBG_ERR, pdfobjects::XPdfObjectFactory::getInstance(), getTrailerDict(), and kernelPrintDbg.
| void CXref::init | ( | ) | [private] |
Core initialization for instance. Called by constructor only.
References checkEncryptedContent(), debug::DBG_CRIT, debug::DBG_ERR, internal_fetch, kernelPrintDbg, and pdfedit_core_dev_init_check().
Referenced by CXref().
| virtual RefState pdfobjects::CXref::knowsRef | ( | const IndiRef & | ref | ) | const [inline, virtual] |
Checks if given reference is known.
| ref | Reference to check. |
Calls knowsRef(::Ref) method. This is just for easy to use wrapper for non xpdf code.
Reimplemented in pdfobjects::XRefWriter.
References pdfobjects::IndiRef::gen, knowsRef(), and pdfobjects::IndiRef::num.
| RefState CXref::knowsRef | ( | const ::Ref & | ref | ) | const [virtual] |
Checks if given reference is known.
| ref | Reference to check. |
Checks if reference is present in newStorage. If found, returns status stored in newStorage. If not found, searches XRef::entries array.
Reimplemented in pdfobjects::XRefWriter.
References check_need_credentials, debug::DBG_DBG, ObjectStorage< K, V, Comp >::get(), kernelPrintDbg, and newStorage.
Referenced by knowsRef().
| void CXref::reopen | ( | size_t | xrefOff, | |
| bool | dropChanges = true | |||
| ) | [protected] |
Reinitializes all internal structures.
| xrefOff | Offset of cross reference table from which to start. | |
| dropChanges | Flag whether to drop changed objects. |
Clears internal revision specific structures and forces XRef super type to throw away all internal structures as well and parse them again from the given stream position.
If the dropChanges flag is true then also all changed objects are droped. This flag should be set to false when we are changing the current revision and kept in default (true) value otherwise (final cleanup, saving as new revision).
References checkEncryptedContent(), cleanUp(), debug::DBG_DBG, and kernelPrintDbg.
Referenced by pdfobjects::XRefWriter::changeRevision(), and pdfobjects::XRefWriter::saveChanges().
| Ref CXref::reserveRef | ( | ) | [protected] |
Reserves reference for new indirect object.
Searches for free object number and generation number and uses it to register reference for new indirect object. Reference is stored to the newStorage with Reserved flag. This is changed to Initialized if real object is stored to the CXref (using change method).
Created object is accesible only if default value has been changed. This means that returned object has to be changed and after change method has to be called. This is mainly because we want to prevent unintialized object inside.
TODO reuse strathegy - REUSE_FIRST, REUSE_AFTER, NOREUSE
| IndirectObjectsExhausted | if all object numbers has been used. |
Reimplemented in pdfobjects::XRefWriter.
References check_need_credentials, ObjectStorage< K, V, Comp >::contains(), debug::DBG_DBG, getNumObjects(), kernelPrintDbg, pdfobjects::MAXOBJGEN, pdfobjects::MAXOBJNUM, newStorage, and ObjectStorage< K, V, Comp >::put().
Referenced by createObject().
| void CXref::setCredentials | ( | const char * | ownerPasswd, | |
| const char * | userPasswd | |||
| ) | [virtual] |
Sets credentials for encrypted documents. This method is mandatory prerequisity if encrypted content is required. If it has not been called before the fetch method is called, it will throw the PermissionException.
If credentials are correct, sets needs_credentials to false, thus enables encrypted content returning.
| NotImplementedException | if document uses unsupported security handler. |
References debug::DBG_DBG, debug::DBG_ERR, debug::DBG_WARN, disableInternalFetch(), enableInternalFetch(), kernelPrintDbg, and needs_credentials.
Referenced by pdfobjects::CPdf::setCredentials().
| bool CXref::typeSafe | ( | ::Object * | obj1, | |
| ::Object * | obj2 | |||
| ) | [virtual] |
Checks whether obj1 can replace obj2.
| obj1 | Original object. | |
| obj2 | Replace object. |
obj2 can replace obj1 only iff at least 1 condition is true:
This means that in indirect value can replace direct one only if both have same value type.
References debug::DBG_DBG, debug::DBG_ERR, fetch(), and kernelPrintDbg.
Referenced by pdfobjects::XRefWriter::paranoidCheck().
ChangedStorage pdfobjects::CXref::changedStorage [protected] |
Object storage for changed objects. Mapping from object referencies to the ObjectEntry structure. This structure contains new Object value for reference and flag.
Referenced by changeObject(), cleanUp(), fetch(), and pdfobjects::XRefWriter::saveChanges().
boost::shared_ptr<Object> pdfobjects::CXref::currTrailer [protected] |
Trailer dictionary for changes. This is allocated on demand when changeTrailer is called for the first time and it is used in getTrailerDict to force changed trailer rather than the one from XRef which is parsed each time reopen method is called.
Instance is cleaned up only if reopen is called with dropChanges flag (in cleanUp method) because this means that we have just created a new revision which is clean.
Referenced by changeTrailer(), cleanUp(), and getTrailerDict().
bool pdfobjects::CXref::internal_fetch [private] |
Flag for internal fetching. This is used when fetch method is requrired and no credentials are prepared yet (and we are sure that fetched object is not encrypted).
Referenced by disableInternalFetch(), enableInternalFetch(), fetch(), and init().
bool pdfobjects::CXref::needs_credentials [private] |
Flag for decryption credentials. Set in constructor if document is encrypted and no credentials are provided. This implies that each method which provides encrypted data throws an exception.
Referenced by checkEncryptedContent(), getNeedCredentials(), and setCredentials().
RefStorage pdfobjects::CXref::newStorage [protected] |
Object storage for newly created objects. Value is the flag of newly created reference. When new entry is added, it should have Reserved state and when changed for the first time Initialized. Unused is default value for not found, so unknown (ObjectStorage returns 0 if entry is not found).
Referenced by changeObject(), cleanUp(), getNumObjects(), knowsRef(), and reserveRef().