o
    ç÷¡gwJ  ã                   @   sL   d dl mZ d dlmZmZmZmZmZ d dlm	Z	m
Z
 G dd„ de	ƒZdS )é    )ÚBytesIO)Úlinefeed_byte_valueÚcrlfÚcr_byteÚlinefeed_byteÚcr_byte_value)ÚClosingContextManagerÚuc                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZd	Zd
Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd@d d!„Zd@d"d#„Zd@d$d%„ZdAd&d'„Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Z e!d0d1„ ƒZ"d2d3„ Z#d4d5„ Z$d6d7„ Z%dBd:d;„Z&d<d=„ Z'd>d?„ Z(dS )CÚBufferedFilezc
    Reusable base class to implement Python-style file buffering around a
    simpler stream.
    i    r   é   é   é   é   é    é@   é€   c                 C   sF   d | _ d| _| j| _tƒ | _tƒ | _d| _d| _	d | _
| _d| _d S )Nr   F)ÚnewlinesÚ_flagsÚ_DEFAULT_BUFSIZEÚ_bufsizer   Ú_wbufferÚbytesÚ_rbufferÚ_at_trailing_crÚ_closedÚ_posÚ_realposÚ_size©Úself© r    ú8/usr/local/lib/python3.10/dist-packages/paramiko/file.pyÚ__init__3   s   
zBufferedFile.__init__c                 C   s   |   ¡  d S ©N)Úcloser   r    r    r!   Ú__del__B   s   zBufferedFile.__del__c                 C   s   | j rtdƒ‚| S )zý
        Returns an iterator that can be used to iterate over the lines in this
        file.  This iterator happens to return the file itself, since a file is
        its own iterator.

        :raises: ``ValueError`` -- if the file is closed.
        zI/O operation on closed file)r   Ú
ValueErrorr   r    r    r!   Ú__iter__E   s   zBufferedFile.__iter__c                 C   s   |   ¡  d| _dS )zN
        Close the file.  Future read and write operations will fail.
        TN)Úflushr   r   r    r    r!   r$   Q   s   
zBufferedFile.closec                 C   s   |   | j ¡ ¡ tƒ | _dS )z{
        Write out any data in the write buffer.  This may do nothing if write
        buffering is not turned on.
        N)Ú
_write_allr   Úgetvaluer   r   r    r    r!   r(   X   s   zBufferedFile.flushc                 C   s   |   ¡ }|st‚|S )a�  
        Returns the next line from the input, or raises ``StopIteration``
        when EOF is hit.  Unlike python file objects, it's okay to mix
        calls to `.next` and `.readline`.

        :raises: ``StopIteration`` -- when the end of the file is reached.

        :returns:
            a line (`str`, or `bytes` if the file was opened in binary mode)
            read from the file.
        )ÚreadlineÚStopIteration)r   Úliner    r    r!   Ú__next__a   s   zBufferedFile.__next__c                 C   ó   | j | j@ | jkS )z±
        Check if the file can be read from.

        :returns:
            `True` if the file can be read from. If `False`, `read` will raise
            an exception.
        )r   Ú	FLAG_READr   r    r    r!   Úreadabler   ó   zBufferedFile.readablec                 C   r/   )z´
        Check if the file can be written to.

        :returns:
            `True` if the file can be written to. If `False`, `write` will
            raise an exception.
        )r   Ú
FLAG_WRITEr   r    r    r!   Úwritable|   r2   zBufferedFile.writablec                 C   ó   dS )z½
        Check if the file supports random access.

        :returns:
            `True` if the file supports random access. If `False`, `seek` will
            raise an exception.
        Fr    r   r    r    r!   Úseekable†   s   zBufferedFile.seekablec                 C   s&   |   t|ƒ¡}||dt|ƒ…< t|ƒS )z°
        Read up to ``len(buff)`` bytes into ``bytearray`` *buff* and return the
        number of bytes read.

        :returns:
            The number of bytes read.
        N)ÚreadÚlen)r   ÚbuffÚdatar    r    r!   Úreadinto�   s   zBufferedFile.readintoNc                 C   sâ  | j rtdƒ‚| j| j@ stdƒ‚|du s|dk rgt| jƒ}tƒ | _|  jt|ƒ7  _	 z|  	| j
¡}W n ty?   d}Y nw |du sJt|ƒdkrO	 t|ƒS | |¡ |  jt|ƒ7  _|  jt|ƒ7  _q,|t| jƒkrˆ| jd|… }| j|d… | _|  jt|ƒ7  _|S t| jƒ|k r×|t| jƒ }| j| j@ r¢t| j|ƒ}z|  	|¡}W n ty´   d}Y nw |du s¿t|ƒdkrÀn|  j|7  _|  jt|ƒ7  _t| jƒ|k s�| jd|… }| j|d… | _|  jt|ƒ7  _|S )a™  
        Read at most ``size`` bytes from the file (less if we hit the end of
        the file first).  If the ``size`` argument is negative or omitted,
        read all the remaining data in the file.

        .. note::
            ``'b'`` mode flag is ignored (``self.FLAG_BINARY`` in
            ``self._flags``), because SSH treats all files as binary, since we
            have no idea what encoding the file is in, or even if the file is
            text data.

        :param int size: maximum number of bytes to read
        :returns:
            data read from the file (as bytes), or an empty string if EOF was
            encountered immediately
        úFile is closedzFile is not open for readingNr   )r   ÚIOErrorr   r0   Ú	bytearrayr   r   r   r8   Ú_readr   ÚEOFErrorÚextendr   ÚFLAG_BUFFEREDÚmaxr   )r   ÚsizeÚresultÚnew_dataÚ	read_sizer    r    r!   r7   œ   sX   
ÿ
ý÷ÿõzBufferedFile.readc           
      C   s¼  | j rtdƒ‚| j| j@ stdƒ‚| j}d}	 | jr@| j| j@ r@t|ƒdkr@|d tkr8|dd… }|  	t
¡ n|  	t¡ d| _|dure|dkret|ƒ|kr^||d… | _|d|… }d}n]|t|ƒ }n| j}t|v sv| j| j@ rwt|v rwnDz|  |¡}W n ty‰   d}Y nw |du s”t|ƒdkr­tƒ | _|  jt|ƒ7  _| j| j@ r©|S t|ƒS ||7 }|  jt|ƒ7  _q| t¡}| j| j@ rÙ| t¡}|dkrÙ||k s×|dk rÙ|}|dkrò|  jt|ƒ7  _| j| j@ rî|S t|ƒS |d }|| tk�r|t|ƒk �r|| tk�r|d7 }|�r||d… | j | _n||d… | _|||… }	|d|… t }t| jƒdk�rC|	tk�rCd| _n|  	|	¡ |  jt|ƒ7  _| j| j@ �rZ|S t|ƒS )	aÍ  
        Read one entire line from the file.  A trailing newline character is
        kept in the string (but may be absent when a file ends with an
        incomplete line).  If the size argument is present and non-negative, it
        is a maximum byte count (including the trailing newline) and an
        incomplete line may be returned.  An empty string is returned only when
        EOF is encountered immediately.

        .. note::
            Unlike stdio's ``fgets``, the returned string contains null
            characters (``'\0'``) if they occurred in the input.

        :param int size: maximum length of returned string.
        :returns:
            next line of the file, or an empty string if the end of the
            file has been reached.

            If the file was opened in binary (``'b'``) mode: bytes are returned
            Else: the encoding of the file is assumed to be UTF-8 and character
            strings (`str`) are returned
        r<   zFile not open for readingFTr   r   Néÿÿÿÿ)r   r=   r   r0   r   r   ÚFLAG_UNIVERSAL_NEWLINEr8   r   Ú_record_newliner   r   r   r   r?   r@   r   r   ÚFLAG_BINARYr	   r   Úfindr   )
r   rD   r-   Ú	truncatedÚnrF   ÚposÚrposÚxposÚlfr    r    r!   r+   ×   s‚   ÿ
þ

ÿÿÙ
)

zBufferedFile.readlinec                 C   sR   g }d}	 |   ¡ }t|ƒdkr	 |S | |¡ |t|ƒ7 }|dur(||kr(	 |S q)a®  
        Read all remaining lines using `readline` and return them as a list.
        If the optional ``sizehint`` argument is present, instead of reading up
        to EOF, whole lines totalling approximately sizehint bytes (possibly
        after rounding up to an internal buffer size) are read.

        :param int sizehint: desired maximum number of bytes to read.
        :returns: list of lines read from the file.
        r   TN)r+   r8   Úappend)r   ÚsizehintÚlinesÚ
byte_countr-   r    r    r!   Ú	readlines@  s   

üøzBufferedFile.readlinesc                 C   ó   t dƒ‚)a¬  
        Set the file's current position, like stdio's ``fseek``.  Not all file
        objects support seeking.

        .. note::
            If a file is opened in append mode (``'a'`` or ``'a+'``), any seek
            operations will be undone at the next write (as the file position
            will move back to the end of the file).

        :param int offset:
            position to move to within the file, relative to ``whence``.
        :param int whence:
            type of movement: 0 = absolute; 1 = relative to the current
            position; 2 = relative to the end of the file.

        :raises: ``IOError`` -- if the file doesn't support random access.
        zFile does not support seeking.©r=   )r   ÚoffsetÚwhencer    r    r!   ÚseekV  s   zBufferedFile.seekc                 C   ó   | j S )zù
        Return the file's current position.  This may not be accurate or
        useful if the underlying file doesn't support random access, or was
        opened in append mode.

        :returns: file position (`number <int>` of bytes).
        )r   r   r    r    r!   Útellj  s   zBufferedFile.tellc                 C   sî   t |tƒr
| d¡}| jrtdƒ‚| j| j@ stdƒ‚| j| j@ s(|  |¡ dS | j	 
|¡ | j| j@ ri| t¡}|dkrg| j	 ¡ }|t|ƒt|ƒ 7 }|  |d|d … ¡ tƒ | _	| j	 
||d d… ¡ dS | j	 ¡ | jkru|  ¡  dS )a8  
        Write data to the file.  If write buffering is on (``bufsize`` was
        specified and non-zero), some or all of the data may not actually be
        written yet.  (Use `flush` or `close` to force buffered data to be
        written out.)

        :param data: ``str``/``bytes`` data to write
        zutf-8r<   zFile not open for writingNr   r   )Ú
isinstanceÚstrÚencoder   r=   r   r3   rB   r)   r   ÚwriteÚFLAG_LINE_BUFFEREDÚrfindr   r*   r8   r   r^   r   r(   )r   r:   Úlast_newline_posÚwbufr    r    r!   rb   t  s,   
	



zBufferedFile.writec                 C   s   |D ]}|   |¡ qdS )a?  
        Write a sequence of strings to the file.  The sequence can be any
        iterable object producing strings, typically a list of strings.  (The
        name is intended to match `readlines`; `writelines` does not add line
        separators.)

        :param sequence: an iterable sequence of strings.
        N)rb   )r   Úsequencer-   r    r    r!   Ú
writelines˜  s   	zBufferedFile.writelinesc                 C   s   | S )z
        Identical to ``iter(f)``.  This is a deprecated file interface that
        predates Python iterator support.
        r    r   r    r    r!   Ú
xreadlines¥  s   zBufferedFile.xreadlinesc                 C   r]   r#   )r   r   r    r    r!   Úclosed¬  s   zBufferedFile.closedc                 C   s   t ƒ ‚)zˆ
        (subclass override)
        Read data from the stream.  Return ``None`` or raise ``EOFError`` to
        indicate EOF.
        )r@   )r   rD   r    r    r!   r?   ²  s   zBufferedFile._readc                 C   rX   )zI
        (subclass override)
        Write data into the stream.
        zwrite not implementedrY   )r   r:   r    r    r!   Ú_writeº  s   zBufferedFile._writec                 C   r5   )ai  
        (subclass override)
        Return the size of the file.  This is called from within `_set_mode`
        if the file is opened in append mode, so the file position can be
        tracked and `seek` and `tell` will work correctly.  If the file is
        a stream that can't be randomly accessed, you don't need to override
        this method,
        r   r    r   r    r    r!   Ú	_get_sizeÁ  s   	zBufferedFile._get_sizeÚrrH   c                 C   s:  | j | _|dk r
d}|dkr|  j| j| jB O  _n)|dkr3|| _|  j| jO  _|  j| j M  _n|dkrC|  j| j| jB  M  _d|v sKd|v rS|  j| jO  _d|v s[d|v rc|  j| jO  _d|v r~|  j| j| jB O  _|  ¡ | _	| j	 | _
| _d|v rŠ|  j| jO  _d|v r›|  j| jO  _d	| _d	S d	S )
zM
        Subclasses call this method to initialize the BufferedFile.
        r   r   rm   ú+ÚwÚaÚbÚUN)r   r   r   rB   rc   r0   r3   ÚFLAG_APPENDrl   r   r   r   rK   rI   r   )r   ÚmodeÚbufsizer    r    r!   Ú	_set_modeÎ  s2   

ûzBufferedFile._set_modec                 C   s€   t |ƒ}t|ƒdkr>|  |¡}||d … }| j| j@ r*|  j|7  _| j | _| _n|  j|7  _|  j|7  _t|ƒdks
d S )Nr   )Ú
memoryviewr8   rk   r   rs   r   r   r   )r   Úraw_datar:   Úcountr    r    r!   r)   ö  s   
ø	zBufferedFile._write_allc                 C   sl   | j | j@ sd S | jd u r|| _d S | j|kr%t| jtƒr%| j|f| _d S || jvr4|  j|f7  _d S d S r#   )r   rI   r   r_   r   )r   Únewliner    r    r!   rJ     s   


ÿzBufferedFile._record_newliner#   )r   )rm   rH   ))Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚSEEK_SETÚSEEK_CURÚSEEK_ENDr0   r3   rs   rK   rB   rc   rI   r"   r%   r'   r$   r(   r.   r1   r4   r6   r;   r7   r+   rW   r\   r^   rb   rh   ri   Úpropertyrj   r?   rk   rl   rv   r)   rJ   r    r    r    r!   r
      sN    	




;
i

$

(r
   N)Úior   Úparamiko.commonr   r   r   r   r   Úparamiko.utilr   r	   r
   r    r    r    r!   Ú<module>   s   