o
    @@i#                     @   s   d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ eeZG dd deZdS )a  
    Xref tables are part of the original PDF file specification
    and one of the features which gives the PDF file format its flexibility.
    A PDF consists of lots of objects and this tells you where they are located in the file.
    This is actually very useful, as a PDF Reader just has to read these values
    and then it loads the objects only when they are needed.
    It does not need to parse or load the whole file.
    N)Decimal)decode_stream)HighLevelTokenizer)	TokenType)
AnyPDFType)
Dictionary)Name)	Reference)Streamc                	       s   e Zd ZdZ fddZdd Zdd Zdeje	j
e	je	jf d	ed
efddZdeje	j
e	je	jf d	efddZded
d fddZdejeef deje	j
e	je	jf d	ed
eje fddZdddZ  ZS )XREFa  
    Xref tables are part of the original PDF file specification
    and one of the features which gives the PDF file format its flexibility.
    A PDF consists of lots of objects and this tells you where they are located in the file.
    This is actually very useful, as a PDF Reader just has to read these values
    and then it loads the objects only when they are needed.
    It does not need to parse or load the whole file.
    c                    s   t t|   g | _i | _d S N)superr   __init___entries_cacheself	__class__ P/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/borb/pdf/xref/xref.pyr   +   s   
zXREF.__init__c                 C   s
   t | jS r   )lenr   r   r   r   r   __len__4   s   
zXREF.__len__c                 C   s(   d}| j D ]}|t|7 }q|d7 }|S )Nzxref
	startxref)sectionsstr)r   outsr   r   r   __str__7   s
   
zXREF.__str__srctokreturnc                    s   | dtj | }td|d }  | |dkrGd fddtddD }|d}|dkr7|| S t|d d}  | |dksdS )Nr   i       c                       g | ]}   qS r   )
_next_byte).0_r    r   r   
<listcomp>N       z.XREF._find_startxref_token.<locals>.<listcomp>s	   startxref)seekioSEEK_ENDtellmaxjoinrangefind)r   r   r    file_lengthposbytes_near_eofidxr   r'   r   _find_startxref_token>   s   


zXREF._find_startxref_tokenc                 C   s   |  ||}|dksJ d|| | }|d usJ | dkrC| }|d us-J | tjks6J t| }|| d S d S )Nr*   zstartxref not found in PDFr   )r7   r+   next_non_comment_tokenget_textget_token_typer   NUMBERint)r   r   r    start_of_xref_token_byte_offsettokenstart_of_xref_offsetr   r   r   _seek_to_xref_tokenY   s   
zXREF._seek_to_xref_tokenrc                 C   s   | j | | S )z2
        Add a new Reference to this XREF
        )r   append)r   rA   r   r   r   addw   s   zXREF.addindirect_referencec              
      s  t  tr jdu r jdusJ | j jd}|dur|S d}t  ts+t  trB fdd| jD }t	|dkr=dS |d  nt  tr] fdd| jD }t	|dkrYdS |d  t  tsdJ  j
sid} jdurt j} }| j| d}|  jdur< jdur<| t j jd|}	t |	tsJ d|	v sJ d	|	v sJ t |	d tr| j|	d |d
|	td< t |	d	 tr| j|	d	 |d
|	td	< t|	d	d}
d|	vrzt|	}	W n ty } z
td j  |d}~ww |	d |
d }t j}t|	d }||k r:tt|fddtd|d D }|d }nd} jdu rP jdusJJ || j j< |S )z
        This function looks up an object in this XREF table.
        Objects can be looked up by Reference, or object number.
        Nc                    s   g | ]}|j t kr|qS r   )object_numberr<   r%   xrD   r   r   r(      s    z#XREF.get_object.<locals>.<listcomp>r   c                       g | ]
}|j  j kr|qS r   rE   rF   rH   r   r   r(      s
    )xref)rE   generation_numberLengthFirst)r   r    DecodedBytesz&unable to inflate stream for object %dc                    r#   r   )read_objectrF   r'   r   r   r(      r)      r*   )
isinstancer	   parent_stream_object_numberrE   r   getr<   r   r   r   	is_in_usebyte_offsetr.   r+   rP   index_in_parent_stream
get_objectrL   r
   r   r   	Exceptionloggerdebugr   r,   BytesIOr1   )r   rD   r   r    
cached_objobjrefsrV   tell_beforestream_object
first_byteexstream_bytesindexlengthlist_of_objsr   )rD   r    r   rX   ~   s   














zXREF.get_object
other_xrefc                    sh   |j D ]. g } jdur fdd| j D }n jdur& fdd| j D }t|dkr1|   q| S )z3
        Merge this XREF with another XREF
        Nc                    rI   r   rJ   rF   rA   r   r   r(      s    zXREF.merge.<locals>.<listcomp>c                    s(   g | ]}|j  j kr|j jkr|qS r   )rS   rW   rF   ri   r   r   r(      s    r   )r   rE   rS   r   rC   )r   rh   duplicate_entriesr   ri   r   merge   s   





z
XREF.merge)rh   r   r!   r   )__name__
__module____qualname____doc__r   r   r   typingUnionr,   BufferedIOBase	RawIOBaser\   r   r<   r7   r@   r	   rC   Optionalr   rX   rk   __classcell__r   r   r   r   r      s8    	


sr   )ro   r,   loggingrp   decimalr   !borb.io.filter.stream_decode_utilr   *borb.io.read.tokenize.high_level_tokenizerr   )borb.io.read.tokenize.low_level_tokenizerr   borb.io.read.typesr   r   r   r	   r
   	getLoggerrl   rZ   r   r   r   r   r   <module>   s   
