a
   -                   @   sX   d dl mZmZmZmZmZ d dlmZmZm	Z	m
Z
mZ d dlmZ G dd deZdS )    )linefeed_byte_valuecrlfcr_bytelinefeed_bytecr_byte_value)BytesIOPY2ubytes_types	text_type)ClosingContextManagerc                   @   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erndd Zndd Zdd Zdd Zdd Zdd  ZdBd"d#ZdCd$d%ZdDd&d'ZdEd(d)Zd*d+ Zd,d- Z d.d/ Z!d0d1 Z"e#d2d3 Z$d4d5 Z%d6d7 Z&d8d9 Z'dFd<d=Z(d>d? Z)d@dA Z*d!S )G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#   1/usr/lib/python3.9/site-packages/paramiko/file.py__init__2   s    zBufferedFile.__init__c                 C   s   |    d S N)closer!   r#   r#   r$   __del__A   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__D   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'   P   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+   W   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`) read from the file.
            readlineStopIterationr"   liner#   r#   r$   nextb   s    
zBufferedFile.nextc                 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`) read from the file.
            r.   r1   r#   r#   r$   __next__s   s    
zBufferedFile.__next__c                 C   s   | 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$   readable   s    zBufferedFile.readablec                 C   s   | j | j@ | jkS )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   s    zBufferedFile.writablec                 C   s   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"   Zbuffdatar#   r#   r$   readinto   s    zBufferedFile.readintoNc                 C   s  | j rtd| j| j@ s"td|du s2|dk r| j}t | _|  jt|7  _z| | j	}W n t
yx   d}Y n0 |du st|dkrq||7 }|  jt|7  _|  jt|7  _qR|S |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
yd   d}Y n0 |du st|dkrq|  j|7  _|  jt|7  _q| 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   r5   r   r   r   r;   _readr   EOFErrorr   FLAG_BUFFEREDmaxr   )r"   sizeresultnew_dataZ	read_sizer#   r#   r$   r:      sN    

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rn|dd }| 	t
 n
| 	t d| _|dur|dkrt||kr||d | _|d| }d}q|t| }n| j}t|v s| j| j@ rt|v rqz| |}W n ty   d}Y n0 |du s0t|dkrdt | _|  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r4|t|k r4|| tkr4|d7 }|rP||d | j | _n||d | _||| }	|d| t }t| jdkr|	tkrd| _n
| 	|	 |  jt|7  _| j| j@ r|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 readingFr   r   NT)r   r?   r   r5   r   r   FLAG_UNIVERSAL_NEWLINEr;   r   _record_newliner   r   r   r   r@   rA   r   r   FLAG_BINARYr	   r   findr   )
r"   rD   r2   Z	truncatednrF   posrposZxposZlfr#   r#   r$   r/      s    











zBufferedFile.readlinec                 C   sL   g }d}|   }t|dkrqH|| |t|7 }|dur||krqHq|S )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   N)r/   r;   append)r"   sizehintlinesZ
byte_countr2   r#   r#   r$   	readlinesP  s    

zBufferedFile.readlinesc                 C   s   t ddS )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.Nr?   )r"   offsetwhencer#   r#   r$   seekf  s    zBufferedFile.seekc                 C   s   | 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$   tellz  s    zBufferedFile.tellc                 C   s   t |tr|d}| jr"td| j| j@ s6td| j| j@ sP| | dS | j	
| | j| j@ r|t}|dkr| j	 }|t|t| 7 }| |d|d   t | _	| j	
||d d  dS | j	 | jkr|   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   )
isinstancer   encoder   r?   r   r7   rB   r,   r   writeFLAG_LINE_BUFFEREDrfindr   r-   r;   r   rW   r   r+   )r"   r<   Zlast_newline_posZwbufr#   r#   r$   rZ     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)rZ   )r"   Zsequencer2   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   s   | j S r&   )r   r!   r#   r#   r$   closed  s    zBufferedFile.closedc                 C   s
   t  dS )z
        (subclass override)
        Read data from the stream.  Return ``None`` or raise ``EOFError`` to
        indicate EOF.
        N)rA   )r"   rD   r#   r#   r$   r@     s    zBufferedFile._readc                 C   s   t ddS )zI
        (subclass override)
        Write data into the stream.
        zwrite not implementedNrS   )r"   r<   r#   r#   r$   _write  s    zBufferedFile._writec                 C   s   dS )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rrG   c                 C   s:  | j | _|dk rd}|dkr4|  j| j| jB O  _nR|dkrf|| _|  j| jO  _|  j| j M  _n |dkr|  j| j| jB  M  _d|v sd|v r|  j| jO  _d|v sd|v r|  j| jO  _d|v r|  j| j| jB O  _|  | _	| j	 | _
| _d|v r|  j| jO  _d|v r6|  j| jO  _d	| _d	S )
zM
        Subclasses call this method to initialize the BufferedFile.
        r   r   rb   +wabUN)r   r   r   rB   r[   r5   r7   FLAG_APPENDra   r    r   r   rJ   rH   r   )r"   modebufsizer#   r#   r$   	_set_mode  s0    


zBufferedFile._set_modec                 C   sn   t |dkrj| |}||d  }| j| j@ rL|  j|7  _| j | _| _q |  j|7  _|  j|7  _q d S )Nr   )r;   r`   r   rh   r    r   r   )r"   r<   countr#   r#   r$   r,     s    
zBufferedFile._write_allc                 C   sd   | j | j@ sd S | jd u r"|| _n>| j|krFt| jtrF| j|f| _n|| jvr`|  j|f7  _d S r&   )r   rH   r   rX   r
   )r"   newliner#   r#   r$   rI     s    

zBufferedFile._record_newline)N)N)N)r   )rb   rG   )+__name__
__module____qualname____doc__r   SEEK_SETSEEK_CURSEEK_ENDr5   r7   rh   rJ   rB   r[   rH   r%   r(   r*   r'   r+   r   r3   r4   r6   r8   r9   r=   r:   r/   rR   rV   rW   rZ   r]   r^   propertyr_   r@   r`   ra   rk   r,   rI   r#   r#   r#   r$   r      sP   	




;
i


$

(r   N)Zparamiko.commonr   r   r   r   r   Zparamiko.py3compatr   r   r	   r
   r   Zparamiko.utilr   r   r#   r#   r#   r$   <module>   s   