o
    vh}<                  	   @   s&  d Z ddlZddlmZ ddlmZ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 ddlmZmZ g d	Zd
Z	 dd Zdd Zdd ZdZdZdkdee defddZdefddZdkdedefddZdefddZ dld d!Z!dmde"fd"d#Z#de"fd$d%Z$dmd&e"fd'd(Z%ed)d*G d+d, d,Z&G d-d. d.e'Z(G d/d0 d0e(Z)G d1d2 d2e)Z*G d3d4 d4e)Z+G d5d6 d6e(Z,G d7d8 d8e)Z-d9d: Z.G d;d< d<eZ/G d=d> d>eZ0G d?d@ d@Z1ddAdBe2dCefdDdEZ3edFZ4edGZ5edHZ6dIee4de6f dJee4ge5f dee5de6f fdKdLZ7dMee4 dee4ddf fdNdOZ8	dkdPee9e:f deee9e:f  fdQdRZ;dkdPe9fdSdTZ<dkdPe9fdUdVZ=G dWdX dXe>Z?dYdZ Z@d[d\ ZAd]d^ ZBdeeCgef fd_d`ZDdaeCdefdbdcZEG ddde deee4 ZFdfee4 dee4 fdgdhZGdidj ZHdS )nz
Utility functions for PDF library.
Taken from PyPDF2 with modifications and additions, see
:ref:`here <pypdf2-license>` for the original license of the PyPDF2 project.

Generally, all of these constitute internal API, except for the exception
classes.
    N)	dataclass)datetimetimezone)Enum)BytesIO)Callable	GeneratorIterableOptionalTypeVarUnion)CancelableAsyncIteratorConsList)PdfErrorPdfReadErrorPdfStrictReadErrorPdfWriteErrorPdfStreamErrorIndirectObjectExpectedget_and_applyOrderedEnumStringWithLanguageis_regular_characterread_non_whitespaceread_until_whitespaceread_until_delimiterread_until_regexskip_over_whitespaceskip_over_commentinstance_testpeek!assert_writable_and_random_accessprepare_rw_output_streamfinalise_outputDEFAULT_CHUNK_SIZEchunked_writechunked_digestchunk_streamr   	Singletonrdisoparselift_iterable_asynci   c                 C   s
   t | dS )N   )roundx r0   T/var/www/html/hyperkenya/venv/lib/python3.10/site-packages/pyhanko/pdf_utils/misc.py<lambda>9      
 r2   c                    s    fddS )Nc                    s
   t |  S N)
isinstancer.   clsr0   r1   r2   =   r3   zinstance_test.<locals>.<lambda>r0   r6   r0   r6   r1   r   <   s   r   c                 c   s^    t | }	 zt|}W n
 ty   Y d S w zt|}W n ty(   tdw ||fV  q)NTzList has odd number of elements)iternextStopIteration
ValueError)lstix1x2r0   r0   r1   	pair_iter@   s   
r@   s    
	 s
   ()<>[]{}/%maxcharsreturnc                 C   s   t t| |dS )a  
    Reads non-whitespace characters and returns them.
    Stops upon encountering whitespace, or, if ``maxchars`` is not ``None``,
    when maxchars is reached.

    :param stream:
        stream to read
    :param maxchars:
        maximal number of bytes to read before returning
    )rA   )_read_until_classPDF_WHITESPACE)streamrA   r0   r0   r1   r   R   s   r   c                 C   s    t tt | }| dtj |S )z
    Read until a token delimiter (i.e. a delimiter character or a PDF
    whitespace character) is encountered, and rewind the stream to the previous
    character.

    :param stream:
        A stream.
    :return:
        The bytes read.
    )rC   rD   PDF_DELIMITERSseekosSEEK_CUR)rE   resultr0   r0   r1   r   a   s   r   class_charsc                    s(   dkrdS  fdd}d | S )Nr       c                  3   sj    d u rd n   } d u s  | k r3d}| v s"|s$d S |V  d u s  | k sd S d S )N   )tellread)stop_attokrL   rA   rE   r0   r1   _buildu   s   
z!_read_until_class.<locals>._build)join)rL   rE   rA   rT   r0   rS   r1   rC   q   s   rC   
byte_valuec                 C   s   | t vo| tvS r4   )rD   rG   )rV   r0   r0   r1   r      s   r   Fc                 C   sx   t d }	 |t v r|s|rdS td| d}|t v s	|dkr!n| dtj t|  t d }q|r:| dtj |S )zQ
    Finds and reads the next non-whitespace character (ignores whitespace).
    r   TrM   Stream ended prematurelyrN      %rF   )rD   r   rP   rH   rI   rJ   r   )rE   	seek_back	allow_eofrR   r0   r0   r1   r      s$   
r   c                 C   s   t d }d}|t v r;| d}|std|d7 }|r7|dkr#|dkS |dkr7| d}|dks2|s6|dkS n|t v s
| dtj |dkS )a  
    Similar to :func:`read_non_whitespace`, but returns a ``bool`` if more than
    one whitespace character was read.

    Will return the cursor to before the first non-whitespace character
    encountered, or after the first end-of-line sequence if one is encountered.
    r   rN   rW      
   rF   )rD   rP   r   rH   rI   rJ   )rE   stop_after_eolrR   cntnxtr0   r0   r1   r      s$   

r   c                 C   sd   |  d}| dd |dkr0|dvr|  d}|dvs|  d}|r.|dkr.| dtj dS dS )a  
    Skip over a comment and position the cursor at the first byte after
    the EOL sequence following the comment. If there is no comment under
    the cursor, do nothing.

    :param stream:
        stream to read
    :return:
        ``True`` if a comment was read.
    rN   rF   rX   )r[   r\   rM   r[   TF)rP   rH   rI   rJ   )rE   rR   r_   r0   r0   r1   r      s   


r   
ignore_eofc                 C   sr   d}	 |  d}|s|r|S td||}|dur4||d|  7 }| | t| d 	 |S ||7 }q)ah  
    Reads until the regular expression pattern matched (ignore the match)
    Raise :class:`PdfStreamError` on premature end-of-file.

    :param stream:
        stream to search
    :param regex:
        regex to match
    :param ignore_eof:
        if true, ignore end-of-line and return immediately
    :raises PdfStreamError:
        on premature EOF
    rM   T   zStream has ended unexpectedlyNrN   )rP   r   searchstartrH   len)rE   regexr`   namerR   mr0   r0   r1   r      s   

r   T)frozenc                   @   sB   e Zd ZU dZeed< dZee ed< dZee ed< dd Z	dS )r   z2
    A string with a language attached to it.
    valueN	lang_codecountry_codec                 C   s   | j S r4   )ri   selfr0   r0   r1   __str__   s   zStringWithLanguage.__str__)
__name__
__module____qualname____doc__str__annotations__rj   r
   rk   rn   r0   r0   r0   r1   r      s   
 r   c                       s"   e Zd Zdef fddZ  ZS )r   msgc                    s   || _ t j|g|R   d S r4   )ru   super__init__)rm   ru   args	__class__r0   r1   rw     s   zPdfError.__init__)ro   rp   rq   rs   rw   __classcell__r0   r0   ry   r1   r     s    r   c                   @      e Zd ZdS )r   Nro   rp   rq   r0   r0   r0   r1   r   	      r   c                   @   r|   )r   Nr}   r0   r0   r0   r1   r     r~   r   c                       s(   e Zd Zddee f fddZ  ZS )r   Nru   c                    s   t  j|pdd d S )Nzindirect object expected)ru   )rv   rw   )rm   ru   ry   r0   r1   rw     s   zIndirectObjectExpected.__init__r4   )ro   rp   rq   r
   rs   rw   r{   r0   r0   ry   r1   r     s     r   c                   @   r|   )r   Nr}   r0   r0   r0   r1   r     r~   r   c                   @   r|   )r   Nr}   r0   r0   r0   r1   r     r~   r   c                    s(   t t  fdd} | fS )Nc                   3   s     V  E d H  d S r4   r0   r0   firstitrr0   r1   _itr"  s   zpeek.<locals>._itr)r8   r9   )r   r   r0   r   r1   r      s   
r    c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   z6
    Ordered enum (from the Python documentation)
    c                 C   s   | j |j u r| j|jkS tr4   rz   ri   NotImplementedErrorrm   otherr0   r0   r1   __ge__.     zOrderedEnum.__ge__c                 C   s   | j |j u r| j|jkS tr4   r   r   r0   r0   r1   __gt__3  r   zOrderedEnum.__gt__c                 C   s   | j |j u r| j|jkS tr4   r   r   r0   r0   r1   __le__8  r   zOrderedEnum.__le__c                 C   s   | j |j u r| j|jk S tr4   r   r   r0   r0   r1   __lt__=  r   zOrderedEnum.__lt__Nro   rp   rq   rr   r   r   r   r   r0   r0   r0   r1   r   )  s    r   c                   @   r   )VersionEnumz
    Ordered enum with support for ``None``, for future-proofing version-based
    enums. In such enums, the value ``None`` can be used as a stand-in for
    "any future version".
    c                 C   s<   | j |j u r| j}|j}|d u rdS |d u rdS ||kS tNTFr   rm   r   val	other_valr0   r0   r1   r   J     zVersionEnum.__ge__c                 C   s@   | j |j u r| j}|j}|d u r|d uS |d u rdS ||kS tNFr   r   r0   r0   r1   r   V     zVersionEnum.__gt__c                 C   s<   | j |j u r| j}|j}|d u rdS |d u rdS ||kS tr   r   r   r0   r0   r1   r   b  r   zVersionEnum.__le__c                 C   s@   | j |j u r| j}|j}|d u r|d uS |d u rdS ||k S tr   r   r   r0   r0   r1   r   n  r   zVersionEnum.__lt__Nr   r0   r0   r0   r1   r   C  s    r   c                   @   s   e Zd Zdd Zdd ZdS )LazyJoinc                 C   s   || _ || _d S r4   )sepiterator)rm   r   r   r0   r0   r1   rw   |  s   
zLazyJoin.__init__c                 C   s   | j | jS r4   )r   rU   r   rl   r0   r0   r1   rn        zLazyJoin.__str__N)ro   rp   rq   rw   rn   r0   r0   r0   r1   r   {  s    r   )default
dictionaryfunctionc                C   s*   z	| | }W ||S  t y   | Y S w r4   )KeyError)r   keyr   r   ri   r0   r0   r1   r     s   
r   XYRgenfuncc              
   c   sD    	 z	|t | V  W n ty  } z	|jW  Y d }~S d }~ww qr4   )r9   r:   ri   )r   r   er0   r0   r1   map_with_return  s   r   r/   c                 c   s    | E d H  d S r4   r0   r.   r0   r0   r1   _as_gen  s   r   temp_bufferc                 c   s    d}|d u s||k rN| }|d ur#|| }|t | k r#t| d | }||}||7 }|s0d S |t |k r?t|d | }n|}|V  |d u s||k sd S d S )Nr   )rd   
memoryviewreadinto)r   rE   max_read
total_readread_bufferto_read
bytes_readto_feedr0   r0   r1   r'     s"   
r'   c                 C   "   t | ||dD ]}|| qd S N)r   )r'   update)r   rE   mdr   chunkr0   r0   r1   r&        r&   c                 C   r   r   )r'   write)r   rE   outputr   r   r0   r0   r1   r%     r   r%   c                   @   s   e Zd Zdd ZdS )r(   c                    s,   t | |||}t |  fdd|_|S )Nc                    s    S r4   r0   )_instancer0   r1   r2     s    z#Singleton.__new__.<locals>.<lambda>)type__new____call__)mcsrf   basesdctr7   r0   r   r1   r     s   
zSingleton.__new__N)ro   rp   rq   r   r0   r0   r0   r1   r(     s    r(   c                 C   s    |   std|  o|  S )z
    Raise an error if the buffer in question is not writable, and return
    a boolean to indicate whether it supports random-access reading.

    :param output:
    :return:
    zOutput buffer is not writable)writableIOErrorseekablereadabler   r0   r0   r1   r!     s   r!   c                 C   s$   | du r	t  } | S t| st  } | S )aB  
    Prepare an output stream that supports both reading and writing.
    Intended to be used for writing & updating signed files:
    when producing a signature, we render the PDF to a byte buffer with
    placeholder values for the signature data, or straight to the provided
    output stream if possible.

    More precisely: this function will return the original output stream
    if it is writable, readable and seekable.
    If the ``output`` parameter is ``None``, not readable or not seekable,
    this function will return a :class:`.BytesIO` instance instead.
    If the ``output`` parameter is not ``None`` and not writable,
    :class:`.IOError` will be raised.

    :param output:
        A writable file-like object, or ``None``.
    :return:
        A file-like object that supports reading, writing and seeking.
    N)r   r!   r   r0   r0   r1   r"     s   r"   c                 C   s@   | dur| |urt |tsJ | }| | |  | S |S )z
    Several internal APIs transparently replaces non-readable/seekable
    buffers with BytesIO for signing operations, but we don't want to
    expose that to the public API user.
    This internal API function handles the unwrapping.
    N)r5   r   	getbufferr   release)orig_outputreturned_outputraw_bufr0   r0   r1   r#     s   
r#   c                  C   s,   z	ddl m}  | W S  ty   tj Y S w )Nr   )r*   )dateutil.parserr*   ImportErrorr   fromisoformat)parser0   r0   r1   _get_isoparse  s   
r   dt_strc                 C   s*   t  }|| }|jd u r|jtjd}|S )N)tzinfo)r   r   replacer   utc)r   r   dtr0   r0   r1   r*     s
   
r*   c                   @   s4   e Zd ZdefddZdd Zdee fddZd	S )
_LiftedIterablerB   c                    s   t | jS r4   )r9   r=   rl   r0   r0   r1   	__anext__"  s   
z_LiftedIterable.__anext__c                    s   d S r4   r0   rl   r0   r0   r1   cancel%  s   z_LiftedIterable.cancelr=   c                 C   s   t || _d S r4   )r8   r=   )rm   r=   r0   r0   r1   rw   (  r   z_LiftedIterable.__init__N)ro   rp   rq   r   r   r   r	   rw   r0   r0   r0   r1   r   !  s    r   r=   c                 C   s   t | S r4   )r   )r=   r0   r0   r1   r+   ,  s   r+   c                  G   s   | D ]
}|d ur|  S qd S r4   r0   )rx   argr0   r0   r1   coalesce0  s
   r   r4   )FF)F)Irr   rI   dataclassesr   r   r   enumr   ior   typingr   r   r	   r
   r   r   pyhanko_certvalidator.utilr   r   __all__r$   r)   r   r@   rD   rG   intbytesr   r   rC   r   r   boolr   r   r   r   	Exceptionr   r   r   r   r   r   r    r   r   r   dictr   r   r   r   r   r   	bytearrayr   r'   r&   r%   r   r(   r!   r"   r#   rs   r   r*   r   r+   r   r0   r0   r0   r1   <module>   s    	 !
 8	
 

	