
    lcL                     n   d Z ddlZddlZ	 ddlZddlZddlZn# e$ r dZY nw xY wddl	Z
ddlZ
ddl
mZ  ej        e          ZeeefZ	 dZdZ	 dxZZ	 dZ	 dZ	 d	Zd
ZddZ G d de          Zd Zd Z d Z!eeddfdZ" G d de#          Z$ G d dej%                  Z& G d dej%                  Z'dS )zAImplements file-like objects for reading and writing to/from GCS.    NT)	constants*gsi   i   )i4  )      c                 6    |t           }|d| |fz  S d| ||fz  S )Nzbytes %d-/%szbytes %d-%d/%s)_UNKNOWN)startstopends      .lib/python3.11/site-packages/smart_open/gcs.py_make_range_stringr   1   s:       -,,udC000    c                        e Zd Z fdZ xZS )UploadFailedErrorc                 t    t          t          |                               |           || _        || _        dS )a^  Raise when a multi-part upload to GCS returns a failed response status code.

        Parameters
        ----------
        message: str
            The error message to display.
        status_code: int
            The status code returned from the upload response.
        text: str
            The text returned from the upload response.

        N)superr   __init__status_codetext)selfmessager   r   	__class__s       r   r   zUploadFailedError.__init__@   s7     	&&//888&			r   )__name__
__module____qualname__r   __classcell__)r   s   @r   r   r   ?   s8                r   r   c                     | j         }| j        }|dz  }dt                      z  }t          || j         | j                  )N      Azupload failed (status code: %(status_code)d, response text: %(response_text)s), part #%(part_num)d, %(total_size)d bytes (total %(total_size_gb).3fGB), headers: %(headers)r)r   r   localsr   )	responsepart_numcontent_length
total_sizeheadersr   response_texttotal_size_gbmsgs	            r   _failr)   R   sH    &KMM,M	gC C!5x}
E
EEr   c                     t           j                            |           }|j        t          k    sJ |j        }|j                            d          }t          t          ||          S )N/)scheme	bucket_idblob_id)	
smart_openutilssafe_urlsplitr,   SCHEMEnetlocpathlstripdict)uri_as_stringsrr-   r.   s       r   	parse_urir9   ^   sZ    			'	'	6	6B9	IgnnS!!GvGDDDDr   c                     t          |           }t          j                            t          |          }t	          |d         |d         |fi |S )Nr-   r.   )r9   r/   r0   check_kwargsopen)urimodetransport_params
parsed_urikwargss        r   open_urirB   f   sJ    3J**41ABBF
;'I)>OOOOOr   c                     |t           j        k    rt          | ||t           j        |          }n7|t           j        k    rt          | ||||          }nt          d|z            ||_        |S )a  Open an GCS blob for reading or writing.

    Parameters
    ----------
    bucket_id: str
        The name of the bucket this object resides in.
    blob_id: str
        The name of the blob within the bucket.
    mode: str
        The mode for opening the object.  Must be either "rb" or "wb".
    buffer_size: int, optional
        The buffer size to use when performing I/O. For reading only.
    min_part_size: int, optional
        The minimum part size for multipart uploads.  For writing only.
    client: google.cloud.storage.Client, optional
        The GCS client to use when working with google-cloud-storage.
    blob_properties: dict, optional
        Set properties on blob before writing.  For writing only.

    )buffer_sizeline_terminatorclient)min_part_sizerF   blob_propertiesz'GCS support for mode %r not implemented)r   READ_BINARYReaderBINARY_NEWLINEWRITE_BINARYWriterNotImplementedErrorname)r-   r.   r>   rD   rG   rF   rH   fileobjs           r   r<   r<   l   s    : y$$ T#%4
 
 
 
'	' 	T'+
 
 
 ""Kd"RSSSGLNr   c                   ,    e Zd ZdZd Zd ZddZd ZdS )	
_RawReaderzRead an GCS object.c                 0    || _         || _        d| _        d S )Nr   )_blob_size	_position)r   gcs_blobsizes      r   r   z_RawReader.__init__   s    

r   c                     || _         | j         S )zSeek to the specified position (byte offset) in the GCS key.

        :param int position: The byte offset from the beginning of the key.

        Returns the position after seeking.
        )rV   )r   positions     r   seekz_RawReader.seek   s     "~r   c                     | j         | j        k    rdS |                     |          }| xj         t          |          z  c_         |S )Nr   )rV   rU   _download_blob_chunklen)r   rX   binarys      r   readz_RawReader.read   sF    >TZ' 	3**400#f++%r   c                     | j         x}}|| j        k    rd}nC|dk    r| j                            |          }n!||z   }| j                            ||          }|S )Nr   r\   )r
   )r
   r   )rV   rU   rT   download_as_bytes)r   rX   r
   rZ   r`   r   s         r   r^   z_RawReader._download_blob_chunk   sv    >)tz! 
	H
 FFRZ 	HZ111>>FFT/CZ1131GGFr   Nr\   )r   r   r   __doc__r   r[   ra   r^    r   r   rR   rR      s[                   r   rR   c                       e Zd ZdZeej        dfdZd Zd Z	d Z
d Zej        fdZd	 Zdd
ZddZddZd ZddZddZddZd Zd ZdS )rJ   zReads bytes from GCS.

    Implements the io.BufferedIOBase interface of the standard library.

    :raises google.cloud.exceptions.NotFound: Raised when the blob to read from does not exist.

    Nc                    |#t           j        j                                        }|                    |                              |          | _        | j        *t           j        j                            d|d|          | j        j	        | j        j	        nd| _
        t          | j        | j
                  | _        d| _        || _        t          j                            |          | _        d| _        || _        d | _        d S )Nzblob z not found in r   F)googlecloudstorageClientbucketget_blobrT   
exceptionsNotFoundrX   rU   rR   _raw_reader_current_pos_current_part_sizer/   
bytebuffer
ByteBuffer_current_part_eof_line_terminatorraw)r   rm   keyrD   rE   rF   s         r   r   zReader.__init__   s      	3\)0022F]]6**33C88
: 	^,)222PSPSPSU[U[3\]]](,
JTZ__
%dj$*=="-'2==kJJ	 /
 r   c                 d    t                               d           d| _        d| _        d| _        dS )zFlush and close this stream.zclose: calledN)loggerdebugrT   rv   rq   r   s    r   closezReader.close   s1    _%%%
!r   c                     dS )z+Return True if the stream can be read from.Trf   r~   s    r   readablezReader.readable       tr   c                     dS )zyIf False, seek(), tell() and truncate() will raise IOError.

        We offer only seek support, and no truncate support.Trf   r~   s    r   seekablezReader.seekable   	     tr   c                     t           j        zUnsupported.ioUnsupportedOperationr~   s    r   detachzReader.detach      %%r   c                 6   t                               d||           |t          j        vrt	          dt          j        z            |t          j        k    r|}n%|t          j        k    r| j        |z   }n
| j        |z   }t          j
                            |d| j                  }|| _        | j                            |           t                               d| j                   | j                                         | j        | j        k    | _        | j        S )zSeek to the specified position.

        :param int offset: The offset in bytes.
        :param int whence: Where the offset is from.

        Returns the position after seeking.z seeking to offset: %r whence: %rz"invalid whence, expected one of %rr   zcurrent_pos: %r)r|   r}   r   WHENCE_CHOICES
ValueErrorWHENCE_STARTWHENCE_CURRENTrr   rU   r/   r0   clamprq   r[   rv   emptyrw   )r   offsetwhencenew_positions       r   r[   zReader.seek  s    	7HHH11 	^AID\\]]]Y++ 	/!LLy// 	/,v5LL:.L!'--lAtzJJ(l+++&(9:::  """%3	  r   c                     | j         S )z,Return the current position within the file.)rr   r~   s    r   tellzReader.tell%  s      r   c                     t           j        r   r   r   rX   s     r   truncatezReader.truncate)  r   r   r\   c                 v   |dk    rdS |dk     r:| j         | _        |                                 | j                                        z   S t          | j                  |k    r|                     |          S | j        r|                                 S |                     |           |                     |          S )z6Read up to size bytes from the object and return them.r   r   )	rU   rr   _read_from_bufferrq   ra   r_   rv   rw   _fill_bufferr   s     r   ra   zReader.read-  s    19 	F3AX 	F $
D))++d.>.C.C.E.EEE
 t!""d* 	0))$///
 9 	,))+++
 	$%%d+++r   c                 .    |                      |          S )zThis is the same as read().)rX   )ra   r   s     r   read1zReader.read1G  s    yydy###r   c                     |                      t          |                    }|sdS ||dt          |          <   t          |          S )zLRead up to len(b) bytes into b, and return the number of bytes
        read.r   N)ra   r_   )r   bdatas      r   readintozReader.readintoK  sG     yyQ   	1*3t99*4yyr   c                 <   |dk    rt          d          t          j                    }| j        rt	          | j                  dk    s| j                                        }| j        |v rF|                    | j                  }|	                    | 
                    |dz                        nZ|	                    | 
                                           |                                  | j        t	          | j                  dk    |                                S )zCRead up to and including the next newline.  Returns the bytes read.r\   z(limits other than -1 not implemented yetr      )rN   r   BytesIOrw   r_   rv   peekrx   indexwriter   r   getvalue)r   limitthe_lineremaining_buffernext_newlines        r   readlinezReader.readlineT  s   B; 	R%&PQQQ:<<9 	$T%7!8!8A!= 	$  $16688$(88 $/55d6KLLt55lQ6FGGHHHt5577888!!### 9 	$T%7!8!8A!= 	$    """r   c                     |dk    r|nt          | j                  }| j                            |          }| xj        t          |          z  c_        |S )z:Remove at most size bytes from our buffer and return them.r   )r_   rv   ra   rr   )r   rX   parts      r   r   zReader._read_from_buffern  sV     qy=ttc$*<&=&=!&&t,,SYY&r   c                 B   |dk    r|n| j         j        }t          | j                   |k     rn| j        si| j                             | j                  }|dk    r!t                              d           d| _        t          | j                   |k     r| j        ed S d S d S d S )Nr   z reached EOF while filling bufferT)rv   _chunk_sizer_   rw   fillrq   r|   r}   )r   rX   
bytes_reads      r   r   zReader._fill_bufferw  s    qyDttd&8&D$$%%, 	!TY 	!+001ABBJQ !?@@@ 		 $$%%, 	!TY 	! 	! 	! 	! 	! 	! 	! 	! 	!r   c                 `    d| j         j        d| j        j        j        d| j        j        dS N(z, )r   r   rT   rm   rO   r~   s    r   __str__zReader.__str__  7     !%!8!8!8$*:K:P:P:PRVR\RaRaRabbr   c                 n    | j         j        d| j        j        j        d| j        j        d| j        dS )N(bucket=, blob=z, buffer_size=r   )r   r   rT   rm   rO   rs   r~   s    r   __repr__zReader.__repr__  s?    N###TZ%6%;%;%;TZ___dNeNeNe
 	
r   Nrd   )r   r   r   re   DEFAULT_BUFFER_SIZEr   rK   r   r   r   r   r   r   r[   r   r   ra   r   r   r   r   r   r   r   rf   r   r   rJ   rJ      sP         ,%4   B         & & & #,"8 ! ! ! !4! ! !& & & &, , , ,4$ $ $ $  # # # #4   ! ! ! !c c c
 
 
 
 
r   rJ   c                       e Zd ZdZeddfdZd Zd Zed             Z	d Z
d Zej        fd	Zdd
Zd Zd Zd Zd ZddZd Zd Zd Zd Zd ZdS )rM   z]Writes bytes to GCS.

    Implements the io.BufferedIOBase interface of the standard library.Nc                    |#t           j        j                                        }|| _        | j                            |                              |          | _        |t          z  dk    s
J d            |t          k    s
J d            || _
        d| _        d| _        d| _        t          j                    | _        t           j        j        j                            |j                  | _        |r0|                                D ]\  }}t1          | j        ||           | j                                        | _        d | _        d S )Nr   z)min part size must be a multiple of 256KBz(min part size must be greater than 256KB)ri   rj   rk   rl   _clientrm   blobrT   _REQUIRED_CHUNK_MULTIPLE_MIN_MIN_PART_SIZE_min_part_size_total_size_total_parts_bytes_uploadedr   r   rv   auth	transportrequestsAuthorizedSession_credentials_sessionitemssetattrcreate_resumable_upload_session_resumable_upload_urlry   )r   rm   r   rG   rF   rH   kvs           r   r   zWriter.__init__  s:     	3\)0022F\((0055d;;
771<ii>iiii 22^^4^^^^+ Z\\-6HHI\]] 	*'--// * *1
Aq))))
 &*Z%O%O%Q%Q"
 r   c                     d S r   rf   r~   s    r   flushzWriter.flush  s    r   c                     t                               d           | j        s=| j        dk    r|                                  n|                     d           d | _        t                               d           d S )Nclosingr   T)is_lastzsuccessfully closed)r|   r}   closedr   _upload_empty_part_upload_partr   r~   s    r   r   zWriter.close  sz    Y{ 	 1$ 0''))))!!$!///DL*+++++r   c                     | j         d u S r   )r   r~   s    r   r   zWriter.closed  s    |t##r   c                     dS )z+Return True if the stream supports writing.Trf   r~   s    r   writablezWriter.writable  r   r   c                     dS )zIf False, seek(), tell() and truncate() will raise IOError.

        We offer only tell support, and no seek or truncate support.Trf   r~   s    r   r   zWriter.seekable  r   r   c                     t           j        r   r   )r   r   r   s      r   r[   zWriter.seek  r   r   c                     t           j        r   r   r   s     r   r   zWriter.truncate  r   r   c                     | j         S )z#Return the current stream position.)r   r~   s    r   r   zWriter.tell  s    r   c                 *    t          j        d          )Nzdetach() not supportedr   r~   s    r   r   zWriter.detach  s    %&>???r   c                 r   t          |t                    s't          dt          dt          |                    | j                            |           | xj        t          |          z  c_        | j                                        | j	        k    r| 
                                 t          |          S )zWrite the given bytes (binary string) to the GCS file.

        There's buffering happening under the covers, so this may not actually
        do any HTTP transfer right away.zinput must be one of z, got: )
isinstance_BINARY_TYPES	TypeErrortyperv   r   r   r_   r   r   r   )r   r   s     r   r   zWriter.write  s     !]++ 	[)---QUVWQXQXQXYZZZ  ###CFF" ""$$t':: 	 1vvr   c                 D    | j                             | j                   dS )z'Cancel the underlying resumable upload.N)r   deleter   r~   s    r   	terminatezWriter.terminate  s#    
 	T788888r   Fc                    | j         dz   }| j                                        }|| j        z  }|r| j        |z   }n|dk    r|t
          z  }d }n||z  }d }| j        |z   dz
  }t          | j        ||          }t          |          |d}t          	                    d|||dz  |           | j        
                    d           | j                            | j        | j                            |          |          }	|rt          }
nt           }
|	j        |
vrt%          |	||| j        |           t                              d|z             | xj         dz  c_         | xj        |z  c_        t+          j        | j                                                  | _        | j        
                    dt*          j                   d S )	Nr   r   )r   )Content-LengthzContent-Rangez6uploading part #%i, %i bytes (total %.3fGB) headers %rr   )r   r%   zupload of part #%i finished)r   rv   r   r   r   r   r   strr|   infor[   r   putr   ra   _UPLOAD_COMPLETE_STATUS_CODES_UPLOAD_INCOMPLETE_STATUS_CODESr   r)   r   r}   r   r   SEEK_END)r   r   r"   r#   	remainderr   
range_stopcontent_ranger%   r!   expecteds              r   r   zWriter._upload_part  s   $q( +0022"T%88	 	&7CC!^ 	66NCCi'NC)N:Q>
*4+?QTUUU!.11*
 
 	Dnj;&>	
 	
 	
 	"""=$$&#((88 % 
 
  	74HH6Hx/ 	Q(Hnd6FPPP2X=>>>Q.
  Z(:(?(?(A(ABB2;/////r   c                     t                               d           ddi}| j                            | j        |          }|j        t          vr t          || j        dz   d| j	        |           | xj        dz  c_        d S )Nzcreating empty filer   0)r%   r   r   )
r|   r}   r   r   r   r   r   r)   r   r   )r   r%   r!   s      r   r   zWriter._upload_empty_part>  s    *+++#S)=$$T%?$QQ'DD 	Q(D-11d6FPPPQr   c                     | S r   rf   r~   s    r   	__enter__zWriter.__enter__G  s    r   c                 ^    ||                                   d S |                                  d S r   )r   r   )r   exc_typeexc_valexc_tbs       r   __exit__zWriter.__exit__J  s1     	NNJJLLLLLr   c                 `    d| j         j        d| j        j        j        d| j        j        dS r   r   r~   s    r   r   zWriter.__str__P  r   r   c                 n    | j         j        d| j        j        j        d| j        j        d| j        dS )Nr   r   z, min_part_size=r   )r   r   rT   rm   rO   r   r~   s    r   r   zWriter.__repr__S  s?    N###TZ%6%;%;%;TZ___dNaNaNa
 	
r   r   )F)r   r   r   re   _DEFAULT_MIN_PART_SIZEr   r   r   propertyr   r   r   r   r   r[   r   r   r   r   r   r   r   r  r  r   r   rf   r   r   rM   rM     si       K K 1 # # # #J  , , , $ $ X$     #,"8 & & & && & & &     @ @ @  .9 9 990 90 90 90v      c c c
 
 
 
 
r   rM   )NN)(re   r   logginggoogle.cloud.exceptionsri   google.cloud.storagegoogle.auth.transport.requestsImportErrorMISSING_DEPSsmart_open.bytebufferr/   smart_open.utilsr   	getLoggerr   r|   bytes	bytearray
memoryviewr   r	   r2   r   r   r	  r   r   r   r   	Exceptionr   r)   r9   rB   r<   objectrR   BufferedIOBaserJ   rM   rf   r   r   <module>r     s0   H G 				 """")))))   LLL                    		8	$	$	:. J	 0: : - U%  9   .")  * 1 1 1 1    	   &	F 	F 	FE E EP P P ((1 1 1 1h' ' ' ' ' ' ' 'T{
 {
 {
 {
 {
R {
 {
 {
|N
 N
 N
 N
 N
R N
 N
 N
 N
 N
s    ##