U
    M8c;                     @   s   d dl Z d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZmZmZ d dlmZ d d	l
mZ d d
lmZ e eZG dd deZdd ZdS )    N)IOBase)ProtocolError)ReadTimeoutError)parsers)set_socket_timeout)IncompleteReadErrorr   ResponseStreamingError)ScalarTypes)XMLParseError)first_non_none_responsec                   @   s   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zd#ddZ	dd Z
dd Zdd Zdd Zdd ZeZedfddZefddZdd Zdd  Zd!d" ZdS )$StreamingBodyae  Wrapper class for an http response body.

    This provides a few additional conveniences that do not exist
    in the urllib3 model:

        * Set the timeout on the socket (i.e read() timeouts)
        * Auto validation of content length, if the amount of bytes
          we read does not match the content length, an exception
          is raised.

    i   c                 C   s   || _ || _d| _d S )Nr   )_raw_stream_content_length_amount_read)selfZ
raw_streamcontent_length r   5/tmp/pip-unpacked-wheel-ozje0y8b/botocore/response.py__init__5   s    zStreamingBody.__init__c                 C   s   d S Nr   r   r   r   r   __del__:   s    zStreamingBody.__del__c                 C   s:   zt | j| W n$ tk
r4   tjddd  Y nX dS )z&Set the timeout seconds on the socket.zbCannot access the socket object of a streaming response.  It's possible the interface has changed.T)exc_infoN)r   r   AttributeErrorloggererror)r   timeoutr   r   r   r   @   s    z StreamingBody.set_socket_timeoutc                 C   s(   z| j  W S  tk
r"   Y dS X d S )NF)r   readabler   r   r   r   r   r   W   s    zStreamingBody.readableNc              
   C   s   z| j |}W nZ tk
r@ } zt|j|dW 5 d}~X Y n, tk
rj } zt|dW 5 d}~X Y nX |  jt|7  _|dks|s|dkr| 	  |S )zhRead at most amt bytes from the stream.

        If the amt argument is omitted, read all data.
        )Zendpoint_urlr   N)r   r   )
r   readURLLib3ReadTimeoutErrorr   urlURLLib3ProtocolErrorr   r   len_verify_content_length)r   amtchunker   r   r   r   ]   s    zStreamingBody.readc                 C   s
   | j  S r   )r   	readlinesr   r   r   r   r'   q   s    zStreamingBody.readlinesc                 C   s   |  | jS )z:Return an iterator to yield 1k chunks from the raw stream.)iter_chunks_DEFAULT_CHUNK_SIZEr   r   r   r   __iter__t   s    zStreamingBody.__iter__c                 C   s   |  | j}|r|S t dS )z-Return the next 1k chunk from the raw stream.N)r   r)   StopIteration)r   current_chunkr   r   r   __next__x   s    zStreamingBody.__next__c                 C   s   | j S r   )r   r   r   r   r   	__enter__   s    zStreamingBody.__enter__c                 C   s   | j   d S r   r   close)r   typevalue	tracebackr   r   r   __exit__   s    zStreamingBody.__exit__Fc                 c   sd   d}|  |D ]<}|| d}|dd D ]}||d V  q,|d }q|r`||d V  dS )zReturn an iterator to yield lines from the raw stream.

        This is achieved by reading chunk of bytes (of size chunk_size) at a
        time from the raw stream, and then yielding lines from there.
            TNr   )r(   
splitlines)r   
chunk_sizekeependspendingr%   linesliner   r   r   
iter_lines   s    
zStreamingBody.iter_linesc                 c   s    |  |}|dkrq|V  q dS )z\Return an iterator to yield chunks of chunk_size bytes from the raw
        stream.
        r5   N)r   )r   r8   r,   r   r   r   r(      s    
zStreamingBody.iter_chunksc                 C   s2   | j d k	r.| jt| j kr.t| jt| j dd S )N)Zactual_bytesZexpected_bytes)r   r   intr   r   r   r   r   r#      s    z$StreamingBody._verify_content_lengthc                 C   s
   | j  S r   )r   tellr   r   r   r   r?      s    zStreamingBody.tellc                 C   s   | j   dS )z*Close the underlying http response stream.Nr/   r   r   r   r   r0      s    zStreamingBody.close)N)__name__
__module____qualname____doc__r)   r   r   r   r   r   r'   r*   r-   r.   r4   nextr=   r(   r#   r?   r0   r   r   r   r   r   &   s$   

r   c                 C   sx   | j d }|j|jd}|d dkr0|j|d< n,| jrRt|j|d d|d< n
|j|d< t	|}||
|| jfS )Nprotocol)headersstatus_coderG   i,  bodyrF   zcontent-length)metadatarF   rG   contentZhas_streaming_outputr   rawgetr   create_parserparseZoutput_shape)Zoperation_modelhttp_responserE   Zresponse_dictparserr   r   r   get_response   s"    
 


 rQ   )loggingior   Zurllib3.exceptionsr   r!   r   r   Zbotocorer   Zbotocore.compatr   Zbotocore.exceptionsr   r   r	   r
   Zbotocore.hooksr   	getLoggerr@   r   r   rQ   r   r   r   r   <module>   s   
 