B
    bAZ>*                 @   s~   d Z yddlZW n ek
r(   dZY nX ddlmZ dd Zdd ZeG dd	 d	eZG d
d deZ	G dd deZ
dS )a  
    werkzeug.contrib.iterio
    ~~~~~~~~~~~~~~~~~~~~~~~

    This module implements a :class:`IterIO` that converts an iterator into
    a stream object and the other way round.  Converting streams into
    iterators requires the `greenlet`_ module.

    To convert an iterator into a stream all you have to do is to pass it
    directly to the :class:`IterIO` constructor.  In this example we pass it
    a newly created generator::

        def foo():
            yield "something\n"
            yield "otherthings"
        stream = IterIO(foo())
        print stream.read()         # read the whole iterator

    The other way round works a bit different because we have to ensure that
    the code execution doesn't take place yet.  An :class:`IterIO` call with a
    callable as first argument does two things.  The function itself is passed
    an :class:`IterIO` stream it can feed.  The object returned by the
    :class:`IterIO` constructor on the other hand is not an stream object but
    an iterator::

        def foo(stream):
            stream.write("some")
            stream.write("thing")
            stream.flush()
            stream.write("otherthing")
        iterator = IterIO(foo)
        print iterator.next()       # prints something
        print iterator.next()       # prints otherthing
        iterator.next()             # raises StopIteration

    .. _greenlet: https://github.com/python-greenlet/greenlet

    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
    N)implements_iteratorc             C   s8   t | }t||}t|tr*|d| S |d| S )z2concatenate any string type in an intelligent way.     )iternext
isinstancebytesjoin)iterablesentineliteratorZ
first_item r   6lib/python3.7/site-packages/werkzeug/contrib/iterio.py_mixed_join2   s
    

r   c             C   s   t | trdS dS )N   

)r   r   )Zreference_stringr   r   r   _newline;   s    
r   c               @   s   e Zd ZdZd ddZdd Zdd Zd	d
 Zd!ddZd"ddZ	dd Z
dd Zd#ddZd$ddZd%ddZdd Zdd ZdS )&IterIOa  Instances of this object implement an interface compatible with the
    standard Python :class:`file` object.  Streams are either read-only or
    write-only depending on how the object is created.

    If the first argument is an iterable a file like object is returned that
    returns the contents of the iterable.  In case the iterable is empty
    read operations will return the sentinel value.

    If the first argument is a callable then the stream object will be
    created and passed to that function.  The caller itself however will
    not receive a stream but an iterable.  The function will be be executed
    step by step as something iterates over the returned iterable.  Each
    call to :meth:`flush` will create an item for the iterable.  If
    :meth:`flush` is called without any writes in-between the sentinel
    value will be yielded.

    Note for Python 3: due to the incompatible interface of bytes and
    streams you should set the sentinel value explicitly to an empty
    bytestring (``b''``) if you are expecting to deal with bytes as
    otherwise the end of the stream is marked with the wrong sentinel
    value.

    .. versionadded:: 0.9
       `sentinel` parameter was added.
    r   c             C   s2   yt |}W n tk
r&   t||S X t||S )N)r   	TypeErrorIterIIterO)clsobjr   r   r   r   r   __new__^   s
    zIterIO.__new__c             C   s   | S )Nr   )selfr   r   r   __iter__e   s    zIterIO.__iter__c             C   s   | j rtd| jS )NzI/O operation on closed file)closed
ValueErrorpos)r   r   r   r   tellh   s    zIterIO.tellc             C   s   | j rtddS )NzI/O operation on closed fileF)r   r   )r   r   r   r   isattym   s    zIterIO.isattyr   c             C   s   | j rtdtddd S )NzI/O operation on closed file	   zBad file descriptor)r   r   IOError)r   r   moder   r   r   seekr   s    zIterIO.seekNc             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   sizer   r   r   truncatew   s    zIterIO.truncatec             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   sr   r   r   write|   s    zIterIO.writec             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   listr   r   r   
writelines   s    zIterIO.writelinesc             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   nr   r   r   read   s    zIterIO.readc             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   sizehintr   r   r   	readlines   s    zIterIO.readlinesc             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   lengthr   r   r   readline   s    zIterIO.readlinec             C   s   | j rtdtddd S )NzI/O operation on closed filer!   zBad file descriptor)r   r   r"   )r   r   r   r   flush   s    zIterIO.flushc             C   s"   | j rt |  }|st |S )N)r   StopIterationr1   )r   liner   r   r   __next__   s    zIterIO.__next__)r   )r   )N)r+   )r   )N)__name__
__module____qualname____doc__r   r   r   r    r$   r&   r(   r*   r-   r/   r1   r2   r5   r   r   r   r   r   A   s   





r   c               @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )r   z#Convert an stream into an iterator.r   c             #   s|   t d krtdt| t  _g _d_|_d_	 fdd}t  |j}x|
 }|sjd S |d V  qZW d S )NzIterI requires greenlet supportFr   c                  s        d S )N)closer   )funcstreamr   r   run   s    zIterI.__new__.<locals>.run)greenletRuntimeErrorobjectr   Z
getcurrent_parent_bufferr   r   r   switch)r   r;   r   r=   grvr   )r;   r<   r   r      s    

zIterI.__new__c             C   s   | j sd| _ |   d S )NT)r   _flush_impl)r   r   r   r   r:      s    zIterI.closec             C   s4   | j rtd|r0|  jt|7  _| j| d S )NzI/O operation on closed file)r   r   r   lenrB   append)r   r'   r   r   r   r(      s
    zIterI.writec             C   s   x|D ]}|  | qW d S )N)r(   )r   r)   itemr   r   r   r*      s    
zIterI.writelinesc             C   s   | j rtd|   d S )NzI/O operation on closed file)r   r   rF   )r   r   r   r   r2      s    zIterI.flushc             C   s<   t | j| j}g | _|s*| jr*| j  n| j|f d S )N)r   rB   r   r   rA   rC   )r   datar   r   r   rF      s
    
zIterI._flush_implN)r   )
r6   r7   r8   r9   r   r:   r(   r*   r2   rF   r   r   r   r   r      s   
r   c               @   sZ   e Zd ZdZdddZdd Zdd Zd	d
 ZdddZdddZ	dddZ
dddZdS )r   zCIter output.  Wrap an iterator and give it a stream like interface.r   c             C   s,   t | }||_d |_||_d|_d|_|S )NFr   )r@   r   _gen_bufr   r   r   )r   genr   r   r   r   r   r      s    
zIterO.__new__c             C   s   | S )Nr   )r   r   r   r   r      s    zIterO.__iter__c             C   s    | j s|| _ n|  j |7  _ dS )z[Replace string directly without appending to an empty string,
        avoiding type issues.N)rL   )r   stringr   r   r   _buf_append   s    zIterO._buf_appendc             C   s&   | j s"d| _ t| jdr"| j  d S )NTr:   )r   hasattrrK   r:   )r   r   r   r   r:      s    zIterO.closer   c             C   s   | j rtd|dkr"|| j7 }n8|dkrJ|   t| j| j| | _d S |dkrZtdg }y<t| j}x,||krt| j	}|t|7 }|
| qlW W n tk
r   Y nX |r| t|| j td|| _d S )NzI/O operation on closed file      r   zInvalid argument)r   r   r   r-   minr"   rG   rL   r   rK   rH   r3   rO   r   r   max)r   r   r#   buftmp_end_posrI   r   r   r   r$      s,    


z
IterO.seekr+   c          
   C   s&  | j rtd|dk rP| t| j| j | j| jd  }|  jt|7  _|S | j| }g }yX| jd krndnt| j}x:||ks| jd kr|st	| j}|t|7 }|
| qzW W n tk
r   Y nX |r| t|| j | jd kr| jS td|}z| j| j| S t|t| j| _X d S )NzI/O operation on closed filer   )r   r   rO   r   rK   r   rL   r   rG   r   rH   r3   rT   rS   )r   r,   resultnew_posrU   rV   rI   r   r   r   r-     s2    



z
IterO.readNc          
   C   sF  | j rtdd}| jr.| jt| j| j}g }yn| jd krF| j}n
t| j}xL|dk rt| j}|t|}|	| |dkr|| }P |t|7 }qRW W n t
k
r   Y nX |r| t|| j | jd kr| jS |dk rt| j}n|d }|d k	r| j| |k r| j| }z| j| j| S t|t| j| _X d S )NzI/O operation on closed filer+   r   rQ   )r   r   rL   findr   r   rG   r   rK   rH   r3   rO   r   r   rS   )r   r0   Znl_posrU   r   rI   Z	local_posrX   r   r   r   r1   .  s@    






zIterO.readlinec             C   sV   d}g }|   }x@|rP|| |t|7 }d|  k r@|krFn nP |   }qW |S )Nr   )r1   rH   rG   )r   r.   Ztotallinesr4   r   r   r   r/   V  s    
zIterO.readlines)r   )r   )r+   )N)r   )r6   r7   r8   r9   r   r   rO   r:   r$   r-   r1   r/   r   r   r   r   r      s   
	


(r   )r9   r>   ImportErrorZwerkzeug._compatr   r   r   r@   r   r   r   r   r   r   r   <module>)   s   
	a7