U
    c:                     @   s  U d Z dZ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mZmZmZmZmZmZmZmZ zdd
lmZ W n  ek
r   dd
lmZ Y nX ddlmZmZmZ eeeeef eeeef eeeef f Z ee!d< eeeeeeef Z"ee!d< eZ#ee$e#f Z%dZ&dZ'dZ(dZ)e*e*e*dddZ+dee#ee, e*dddZ-e#e*dddZ.e#e/dddZ0e#ddddZ1e#ee* e*d d!d"Z2e#e,e*d#d$d%Z3e#e*dd&d'Z4e e e d(d)d*Z5e#ddd+d,Z6i Z7eee$e*f e*f e!d-< ee$e*f e*d.d/d0Z8ee$e$d1d2d3Z9ee*e$d1d4d3Z9ee$e*f e$d1d5d3Z9ee$e,d1d6d7Z:ee*e*d1d8d7Z:ee,e,d1d9d7Z:ee,e$e*f ee,e*f d1d:d7Z:e*e*d1d;d<Z;e,e$d=d>d?Z<d@Z=e,e,e,e,dAdBdCZ>dfe$e,ddEdFdGZ?e$ddHdIdJZ@dge$e$e$ddLdMdNZAdhe$e$e$ddLdOdPZBdie$e$ddQdRdSZCdje$e$ddQdTdUZDe$e$ddVdWdXZEe$edYdZd[ZFdke$ee$ef ee$e$f e/d]d^d_ZGe,e$d`dadbZHe	G dcdd ddZIdS )lz"Utility functions for PDF library.zMathieu Fenniakzbiziqe@mathieu.fenniak.net    N
getencoder)	dataclass)DEFAULT_BUFFER_SIZE)SEEK_CUR)	IOAnyCallableDictOptionalPatternTupleUnionoverload)	TypeAlias   )STREAM_TRUNCATED_PREMATURELYDeprecationErrorPdfStreamErrorTransformationMatrixTypeCompressedTransformationMatrixz1{} is deprecated and will be removed in pypdf {}.z-{} is deprecated and was removed in pypdf {}.zD{} is deprecated and will be removed in pypdf 3.0.0. Use {} instead.z={} is deprecated and was removed in pypdf {}. Use {} instead.)header1header2returnc                 C   sf   d}g }| |kr | ||  ||kr8| || t|dkrZtd| d|d|t| S )N)s   %PDF-1.3s   %PDF-1.4s   %PDF-1.5s   %PDF-1.6s   %PDF-1.7s   %PDF-2.0r   zneither z nor z are proper headers)appendindexlen
ValueErrormax)r   r   versionsZpdf_header_indices r    0/tmp/pip-unpacked-wheel-u_n6aelj/pypdf/_utils.py_get_max_pdf_version_headerO   s    r"   )streammaxcharsr   c                 C   s8   d}|  d}| s4|sq4||7 }t||krq4q|S )a;  
    Read non-whitespace characters and return them.

    Stops upon encountering whitespace or when maxchars is reached.

    Args:
        stream: The data stream from which was read.
        maxchars: The maximum number of bytes returned; by default unlimited.

    Returns:
        The data which was read.
        r   )readisspacer   )r#   r$   txttokr    r    r!   read_until_whitespaceb   s    
r*   )r#   r   c                 C   s"   |  d}|tkr|  d}q
|S )z
    Find and read the next non-whitespace character (ignores whitespace).

    Args:
        stream: The data stream from which was read.

    Returns:
        The data which was read.
    r   )r&   WHITESPACESr#   r)   r    r    r!   read_non_whitespacez   s    

r-   c                 C   s0   t d }d}|t kr(| d}|d7 }q|dkS )a  
    Similar to read_non_whitespace, but return a boolean if more than one
    whitespace character was read.

    Args:
        stream: The data stream from which was read.

    Returns:
        True if more than one whitespace was skipped, otherwise return False.
    r   r   )r+   r&   )r#   r)   Zcntr    r    r!   skip_over_whitespace   s    

r.   c                 C   s6   |  d}| dd |dkr2|dkr2|  d}qd S )Nr      %)   
   )r&   seekr,   r    r    r!   skip_over_comment   s
    
r4   )r#   regexr   c                 C   sd   d}|  d}|s|S ||}|dk	rV||d|  7 }| | t| d q`||7 }q|S )z
    Read until the regular expression pattern matched (ignore the match).
    Treats EOF on the underlying stream as the end of the token to be matched.

    Args:
        regex: re.Pattern

    Returns:
        The read bytes.
    r%      Nr   )r&   searchstartr3   r   )r#   r5   namer)   mr    r    r!   read_until_regex   s    


r;   )r#   to_readr   c                 C   s>   |   |k rtd| | t | |}| | t |S )a  
    Given a stream at position X, read a block of size to_read ending at position X.

    This changes the stream's position to the beginning of where the block was
    read.

    Args:
        stream:
        to_read:

    Returns:
        The data which was read.
    z!Could not read malformed PDF file)tellr   r3   r   r&   )r#   r<   r&   r    r    r!   read_block_backwards   s    
r>   c                 C   s   g }d}|   dkrtttt|   }|dkr4qt| |}t|d }|sx|dkrl|| dkrl|d8 }qN|dkrxd}|r|||d d  |dkr|| dkr|d8 }qn
|| |dkr| |d t	 qqd
|ddd S )	a   
    Given a byte stream with current position X, return the previous line.

    All characters between the first CR/LF byte found before X
    (or, the start of the file, if no such byte is found) and position X
    After this call, the stream will be positioned one byte after the
    first non-CRLF character found beyond the first CR/LF byte before X,
    or, if no such byte is found, at the beginning of the stream.

    Args:
        stream: StreamType:

    Returns:
        The data which was read.
    Fr   r   s   
TNr%   r/   )r=   r   r   minr   r>   r   r   r3   r   join)r#   Zline_contentZ
found_crlfr<   blockidxr    r    r!   read_previous_line   s.    


rC   )abr   c                    s   t  fdd| D S )Nc                 3   s(   | ]  t  fd dt D V  qdS )c                 3   s&   | ]}t d d t |D V  qdS )c                 s   s"   | ]\}}t |t | V  qd S N)float).0ijr    r    r!   	<genexpr>  s     z6matrix_multiply.<locals>.<genexpr>.<genexpr>.<genexpr>N)sumzip)rH   colrowr    r!   rK     s     z,matrix_multiply.<locals>.<genexpr>.<genexpr>N)tuplerM   )rH   rE   rO   r!   rK     s   z"matrix_multiply.<locals>.<genexpr>)rQ   )rD   rE   r    rR   r!   matrix_multiply  s    rS   c              	   C   sd   d}|  | d tdd0}|| | |d || | W 5 Q R X |  | d dS )z5Create text file showing current location in context.i  r   zpypdf_pdfLocation.txtwbs   HEREN)r3   openwriter&   )r#   ZradiusZ	output_fhr    r    r!   mark_location  s    
rW   B_CACHE)sr   c                 C   s   t }| |kr||  S t| tr"| S z$| d}t| dk rB||| < |W S  tk
r|   | d}t| dk rt||| < | Y S X d S )Nlatin-1   zutf-8)rX   
isinstancebytesencoder   	Exception)rY   Zbcrr    r    r!   b_'  s    


ra   )rE   r   c                 C   s   d S rF   r    rR   r    r    r!   str_9  s    rb   c                 C   s   d S rF   r    rR   r    r    r!   rb   >  s    c                 C   s   t | tr| dS | S d S )NrZ   )r\   r]   decoderR   r    r    r!   rb   C  s    

c                 C   s   d S rF   r    rR   r    r    r!   ord_J  s    rd   c                 C   s   d S rF   r    rR   r    r    r!   rd   O  s    c                 C   s   d S rF   r    rR   r    r    r!   rd   T  s    c                 C   s   t | trt| S | S rF   )r\   strordrR   r    r    r!   rd   Y  s    
c                 C   s   t d}|| }|d S )N	hex_codecr   r   )rE   ZcoderZcodedr    r    r!   	hexencode_  s    rh   )numr   c                 C   s   t | ddS )NL )hexreplace)ri   r    r    r!   hex_stre  s    rn   )    r1   r2      	    )leftupup_leftr   c                 C   sX   | | | }t ||  }t || }t || }||krD||krD| S ||krP|S |S d S rF   )abs)rr   rs   rt   pZ	dist_leftZdist_upZdist_up_leftr    r    r!   paeth_predictorl  s    rw      )msg
stacklevelr   c                 C   s   t j| t|d d S )N)rz   )warningswarnDeprecationWarning)ry   rz   r    r    r!   	deprecatez  s    r~   )ry   r   c                 C   s   t | d S rF   )r   )ry   r    r    r!   deprecation~  s    r   3.0.0)old_namenew_name
removed_inr   c                 C   s   t t| ||d dS )zIRaise an exception that a feature will be removed, but has a replacement.   N)r~   DEPR_MSGformatr   r   r   r    r    r!   deprecate_with_replacement  s    r   c                 C   s   t t| || dS )zMRaise an exception that a feature was already removed, but has a replacement.N)r   DEPR_MSG_HAPPENEDr   r   r    r    r!   deprecation_with_replacement  s    r   )r9   r   r   c                 C   s   t t| |d dS )zFRaise an exception that a feature will be removed without replacement.r   N)r~   DEPR_MSG_NO_REPLACEMENTr   r9   r   r    r    r!   deprecate_no_replacement  s    r   c                 C   s   t t| | dS )zJRaise an exception that a feature was already removed without replacement.N)r    DEPR_MSG_NO_REPLACEMENT_HAPPENEDr   r   r    r    r!   deprecation_no_replacement  s    r   )ry   srcr   c                 C   s   t ||  dS )a  
    Use this instead of logger.warning directly.

    That allows people to overwrite it more easily.

    ## Exception, warnings.warn, logger_warning
    - Exceptions should be used if the user should write code that deals with
      an error case, e.g. the PDF being completely broken.
    - warnings.warn should be used if the user needs to fix their code, e.g.
      DeprecationWarnings
    - logger_warning should be used if the user needs to know that an issue was
      handled by pypdf, e.g. a non-compliant PDF being read in a way that
      pypdf could apply a robustness fix to still read it. This applies mainly
      to strict=False mode.
    N)logging	getLoggerwarning)ry   r   r    r    r!   logger_warning  s    r   )aliasesr   c                     s   t d fdd}|S )z
    Decorator for deprecated term "bookmark"
    To be used for methods and function arguments
        outline_item = a bookmark
        outline = a collection of outline items
    funcc                    s   t   fdd}|S )Nc                     s   t j| dd | |S )NT)fail)rename_kwargs__name__)argskwargs)r   r   r    r!   wrapper  s    z9deprecation_bookmark.<locals>.decoration.<locals>.wrapper)	functoolswraps)r   r   r   r   r!   
decoration  s    z(deprecation_bookmark.<locals>.decoration)r	   )r   r   r    r   r!   deprecation_bookmark  s    r   F)	func_namer   r   r   c                 C   s   |  D ]~\}}||kr|r0t| d| d||kr^t|  d| d| d| d| d
||||< tj| d| dtd qd	S )
z
    Helper function to deprecate arguments.

    Args:
        func_name: Name of the function to be deprecated
        kwargs:
        aliases:
        fail:
    z# is deprecated as an argument. Use z insteadz received both z and z as an argument. z is deprecated. Use z	 instead.)messagecategoryN)itemsr   	TypeErrorpopr{   r|   r}   )r   r   r   r   Zold_termZnew_termr    r    r!   r     s     r   )r]   r   c                 C   sV   | dk r|  dS | dk r*| d ddS | dk rB| d ddS | d ddS d S )	Ni  z Bytei@B z.1fz kBi ʚ;z MBz GBr    )r]   r    r    r!   _human_readable_bytes  s    
r   c                   @   s:   e Zd ZU eed< eed< edddZedddZdS )	Filer9   data)r   c                 C   s   d| j  dtt| j dS )N
File(name=, data: ))r9   r   r   r   selfr    r    r!   __str__  s    zFile.__str__c                 C   s*   d| j  dtt| j dt| j dS )Nr   r   z, hash: r   )r9   r   r   r   hashr   r    r    r!   __repr__  s    zFile.__repr__N)r   
__module____qualname__re   __annotations__r]   r   r   r    r    r    r!   r     s   
r   )N)rx   )r   )r   )r   )r   )F)J__doc__
__author____author_email__r   r   r{   codecsr   Zdataclassesr   ior   osr   typingr   r   r	   r
   r   r   r   r   r   r   ImportErrorZtyping_extensionserrorsr   r   r   rG   r   r   r   Z
StreamTypere   ZStrByteTyper   r   r   r   r]   r"   intr*   r-   boolr.   r4   r;   r>   rC   rS   rW   rX   ra   rb   rd   rh   rn   r+   rw   r~   r   r   r   r   r   r   r   r   r   r   r    r    r    r!   <module>   s   ,&: 	"        
 
 "