U
    g^                     @   sP   d Z ddlmZ ddlmZmZ ddlmZ ddlmZ dgZ	G dd dZ
d	S )
z2Utilities common to reading and writing PDF files.    )Tuple   )genericmisc)DocumentMetadata)PdfError
PdfHandlerc                   @   s   e Zd ZdZdejedddZeej	dddZ
eedd	d
ZeejdddZeej	dddZeeeef dddZdd Zdd Zdd ZdS )r   zfAbstract class providing a general interface for quering objects
    in PDF readers and writers alike.F)refas_metadata_streamc                 C   s   t dS )aO  
        Retrieve the object associated with the provided reference from
        this PDF handler.

        :param ref:
            An instance of :class:`.generic.Reference`.
        :param as_metadata_stream:
            Whether to dereference the object as an XMP metadata stream.
        :return:
            A PDF object.
        NNotImplementedError)selfr	   r
    r   ?/tmp/pip-unpacked-wheel-owvgwkas/pyhanko/pdf_utils/rw_common.py
get_object   s    zPdfHandler.get_object)returnc                 C   s   t dS )a  
        Returns a view of the document trailer of the document represented
        by this :class:`.PdfHandler` instance.

        The view is effectively read-only, in the sense that any writes
        will not be reflected in the actual trailer (if the handler supports
        writing, that is).

        :return:
            A :class:`.generic.DictionaryObject` representing the current state
            of the document trailer.
        Nr   r   r   r   r   trailer_view    s    zPdfHandler.trailer_viewc                 C   s   t d S Nr   r   r   r   r   document_meta_view0   s    zPdfHandler.document_meta_viewc                 C   s   t dS )zS
        :return: A reference to the document catalog of this PDF handler.
        Nr   r   r   r   r   root_ref4   s    zPdfHandler.root_refc                 C   s   | j  }t|tjst|S )zD
        :return: The document catalog of this PDF handler.
        )r   r   
isinstancer   DictionaryObjectAssertionError)r   rootr   r   r   r   ;   s    
zPdfHandler.rootc                 C   s   t d S r   r   r   r   r   r   document_idD   s    zPdfHandler.document_idc                    s   | j d}t|tjst| }t|tjs4tz|d }W n tk
r\   t }Y nX |d }dk rv| d  kr|k sn t	d fdd  d||t
 S )N/Pages
/Resources/Countr   zPage index out of rangec              	      sT  |  }|d }z|d}W n tk
r2   Y nX | }t|D ]\}}t|tjs`tdt|tjspt	|j
|krtd|  }	|	d }
|
dkr|	d }|  kr|| k rn n |||||j
hB   S ||7 }q@|
dkr@|kr>r
|||f  S z|	d}W n tk
r.   Y nX ||f  S q@|d	7 }q@td
d S )Nz/Kidsr   z0Page tree node children must be indirect objectszCircular reference in page treez/Typer   r   z/Pager   zPage not found)r   raw_getKeyError	enumerater   r   IndirectObjectr   ZPdfReadErrorr   	referencer   )Zfirst_page_ixZpages_obj_refZlast_rsrc_dictZ	refs_seenZ	pages_objZkidsZcur_page_ixZ	kid_indexZkid_refZkidZ	node_typeZ
desc_count_recursepage_ixretrieve_parentr   r   r%   Z   sL    





z,PdfHandler._walk_page_tree.<locals>._recurse)r   r   r   r   r"   r   r   r   r    r   set)r   r&   r'   Zpage_tree_root_refZpage_tree_rootZroot_resourcesZ
page_countr   r$   r   _walk_page_treeI   s    0zPdfHandler._walk_page_treec                 C   s   | j |ddS )a  
        Retrieve the node in the page tree containing the
        page with index ``page_ix``, along with the necessary objects
        to modify it in an incremental update scenario.

        :param page_ix:
            The (zero-indexed) number of the page for which we want to
            retrieve the parent.
            A negative number counts pages from the back of the document,
            with index ``-1`` referring to the last page.
        :return:
            A triple with the ``/Pages`` object (or a reference to it),
            the index of the target page in said ``/Pages`` object, and a
            (possibly inherited) resource dictionary.
        Tr'   r)   r   r&   r   r   r   find_page_container   s    zPdfHandler.find_page_containerc                 C   s   | j |ddS )a  
        Retrieve the page with index ``page_ix`` from the page tree, along with
        the necessary objects to modify it in an incremental update scenario.

        :param page_ix:
            The (zero-indexed) number of the page to retrieve.
            A negative number counts pages from the back of the document,
            with index ``-1`` referring to the last page.
        :return:
            A tuple with a reference to the page object and a
            (possibly inherited) resource dictionary.
        Fr*   r+   r,   r   r   r   find_page_for_modification   s    z%PdfHandler.find_page_for_modificationN)F)__name__
__module____qualname____doc__r   Z	Referenceboolr   propertyr   r   r   r   r   r   r   bytesr   r)   r-   r.   r   r   r   r   r      s&     CN)r2   typingr    r   r   Zmetadata.modelr   r   __all__r   r   r   r   r   <module>   s   