U
    –BÞb ,  ã                   @   s:  U d Z dZdZddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZ ddlmZ ddl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 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ee	e
ef Z ee!e f Z"dZ#dZ$e%e%e%dœdd„Z&dPe ee' e%dœdd„Z(e e%dœdd„Z)e e*dœdd„Z+e ddœdd„Z,dQe ee*e%dœdd „Z-e e'e%d!œd"d#„Z.e e%dœd$d%„Z/eeed&œd'd(„Z0e ddœd)d*„Z1i Z2eee!e%f e%f ed+< ee!e%f e%d,œd-d.„Z3ee!e!d/œd0d1„ƒZ4ee%e!d/œd2d1„ƒZ4ee!e%f e!d/œd3d1„Z4ee!e'd/œd4d5„ƒZ5ee%e%d/œd6d5„ƒZ5ee'e'd/œd7d5„ƒZ5ee'e!e%f ee'e%f d/œd8d5„Z5e%e%d/œd9d:„Z6e'e!d;œd<d=„Z7d>Z8e'e'e'e'd?œd@dA„Z9dRe!e'ddCœdDdE„Z:dSe!e!e!ddGœdHdI„Z;dTe!e!ddJœdKdL„Z<e!e!ddMœdNdO„Z=dS )Uz"Utility functions for PDF library.zMathieu Fenniakzbiziqe@mathieu.fenniak.neté    N©Ú
getencoder)ÚDEFAULT_BUFFER_SIZEÚBufferedReaderÚBufferedWriterÚBytesIOÚFileIO)ÚSEEK_CUR)ÚDictÚOptionalÚPatternÚTupleÚUnionÚoverload)Ú	TypeAliasé   )ÚSTREAM_TRUNCATED_PREMATURELYÚPdfStreamErrorÚTransformationMatrixTypeÚCompressedTransformationMatrixz2{} is deprecated and will be removed in PyPDF2 {}.zE{} is deprecated and will be removed in PyPDF2 3.0.0. 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   ú1/tmp/pip-unpacked-wheel-weujb6sz/PyPDF2/_utils.pyÚ_get_max_pdf_version_headerC   s    r!   )ÚstreamÚmaxcharsr   c                 C   s8   d}|   d¡}| ¡ s4|sq4||7 }t|ƒ|krq4q|S )z~
    Read non-whitespace characters and return them.

    Stops upon encountering whitespace or when maxchars is reached.
    ó    r   )ÚreadÚisspacer   )r"   r#   ÚtxtÚtokr   r   r    Úread_until_whitespaceV   s    
r)   )r"   r   c                 C   s"   |   d¡}|tkr|   d¡}q
|S )zEFind and read the next non-whitespace character (ignores whitespace).r   )r%   ÚWHITESPACES©r"   r(   r   r   r    Úread_non_whitespaceg   s    
r,   c                 C   s0   t d }d}|t kr(|  d¡}|d7 }q|dkS )zr
    Similar to read_non_whitespace, but return a Boolean if more than
    one whitespace character was read.
    r   r   )r*   r%   )r"   r(   Zcntr   r   r    Úskip_over_whitespaceo   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
    
r3   F)r"   ÚregexÚ
ignore_eofr   c                 C   sp   d}|   d¡}|s"|r|S ttƒ‚| |¡}|dk	rb||d| ¡ … 7 }|  | ¡ t|ƒ d¡ ql||7 }q|S )zñ
    Read until the regular expression pattern matched (ignore the match).

    :raises PdfStreamError: on premature end-of-file
    :param bool ignore_eof: If true, ignore end-of-line and return immediately
    :param regex: re.Pattern
    r$   é   Nr   )r%   r   r   ÚsearchÚstartr2   r   )r"   r4   r5   Únamer(   Úmr   r   r    Úread_until_regex„   s    



r;   )r"   Úto_readr   c                 C   sd   |   ¡ |k rtdƒ‚|  | t¡ |  |¡}|  | t¡ t|ƒ|kr`tdt|ƒ› d|› d�ƒ‚|S )zˆGiven a stream at position X, read a block of size
    to_read ending at position X.
    The stream's position should be unchanged.
    z!Could not read malformed PDF filez
EOF: read z, expected ú?)Útellr   r2   r	   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r4qØt| |ƒ}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 }q’n
| |¡ |dkr|  |d t	¡ qØq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.
    Fr   r   s   
TNr$   r.   )r>   r   r   Úminr   r?   r   r   r2   r	   Újoin)r"   Zline_contentZ
found_crlfr<   ÚblockÚidxr   r   r    Úread_previous_line¯   s.    



rD   )Ú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)rI   Úcol©Úrowr   r    rL   æ   s     z,matrix_multiply.<locals>.<genexpr>.<genexpr>N)ÚtuplerN   )rI   ©rF   rP   r    rL   å   s   ÿz"matrix_multiply.<locals>.<genexpr>)rR   )rE   rF   r   rS   r    Úmatrix_multiplyâ   s    þrT   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PyPDF2_pdfLocation.txtÚwbs   HEREN)r2   ÚopenÚwriter%   )r"   ZradiusZ	output_fhr   r   r    Úmark_locationë   s    
rX   Ú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)rY   Ú
isinstanceÚbytesÚencoder   Ú	Exception)rZ   ZbcÚrr   r   r    Úb_ú   s    


rb   )rF   r   c                 C   s   d S rG   r   rS   r   r   r    Ústr_  s    rc   c                 C   s   d S rG   r   rS   r   r   r    rc     s    c                 C   s   t | tƒr|  d¡S | S d S )Nr[   )r]   r^   ÚdecoderS   r   r   r    rc     s    

c                 C   s   d S rG   r   rS   r   r   r    Úord_  s    re   c                 C   s   d S rG   r   rS   r   r   r    re   "  s    c                 C   s   d S rG   r   rS   r   r   r    re   '  s    c                 C   s   t | tƒrt| ƒS | S rG   )r]   ÚstrÚordrS   r   r   r    re   ,  s    
c                 C   s   t dƒ}|| ƒ}|d S )NÚ	hex_codecr   r   )rF   ZcoderZcodedr   r   r    Ú	hexencode2  s    ri   )Únumr   c                 C   s   t | ƒ dd¡S )NÚLÚ )ÚhexÚreplace)rj   r   r   r    Úhex_str9  s    ro   )ó    r0   r1   ó   	ó    )ÚleftÚupÚup_leftr   c                 C   sX   | | | }t ||  ƒ}t || ƒ}t || ƒ}||krD||krD| S ||krP|S |S d S rG   )Úabs)rs   rt   ru   ÚpZ	dist_leftZdist_upZdist_up_leftr   r   r    Úpaeth_predictor@  s    rx   é   )ÚmsgÚ
stacklevelr   c                 C   s   t j| t|d� d S )N)r{   )ÚwarningsÚwarnÚPendingDeprecationWarning)rz   r{   r   r   r    Ú	deprecateN  s    r   ú3.0.0)Úold_nameÚnew_nameÚ
removed_inr   c                 C   s   t t | ||¡dƒ d S ©Né   )r   ÚDEPR_MSGÚformat)r�   r‚   rƒ   r   r   r    Údeprecate_with_replacementR  s    rˆ   )r9   rƒ   r   c                 C   s   t t | |¡dƒ d S r„   )r   ÚDEPR_MSG_NO_REPLACEMENTr‡   )r9   rƒ   r   r   r    Údeprecate_no_replacementX  s    rŠ   )rz   Ú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 PyPDF2, e.g. a non-compliant PDF being read in a way that
      PyPDF2 could apply a robustness fix to still read it. This applies mainly
      to strict=False mode.
    N)ÚloggingÚ	getLoggerÚwarning)rz   r‹   r   r   r    Úlogger_warning\  s    r�   )N)F)ry   )r€   )r€   )>Ú__doc__Ú
__author__Ú__author_email__rŒ   r|   Úcodecsr   Úior   r   r   r   r   Úosr	   Útypingr
   r   r   r   r   r   r   ÚImportErrorZtyping_extensionsÚerrorsr   r   rH   r   Ú__annotations__r   Z
StreamTyperf   ZStrByteTyper‰   r†   r^   r!   Úintr)   r,   Úboolr-   r3   r;   r?   rD   rT   rX   rY   rb   rc   re   ri   ro   r*   rx   r   rˆ   rŠ   r�   r   r   r   r    Ú<module>   sŒ    &ÿÿ	 ÿ  þ4 þ	" ÿ  þ