
    @fّ                     L   d Z ddlZddlZddlZddlZ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mZmZmZmZmZmZmZmZmZmZmZmZ  G d d	e           Z! G d
 de!          Z" G d de!          Z# G d de!ej$                  Z$d Z%d Z&d Z'd Z(d Z)dS )zVirtual bases classes for uploading media via Google APIs.

Supported here are:

* simple (media) uploads
* multipart uploads that contain both metadata and a small file as payload
* resumable uploads (with metadata as well)
    N)_async_resumable_media)_helpers)_upload)common)_CONTENT_TYPE_HEADER_CONTENT_RANGE_TEMPLATE_RANGE_UNKNOWN_TEMPLATE_EMPTY_RANGE_TEMPLATE_BOUNDARY_FORMAT_MULTIPART_SEP_CRLF_MULTIPART_BEGIN_RELATED_HEADER_BYTES_RANGE_RE_STREAM_ERROR_TEMPLATE_POST_PUT!_UPLOAD_CHECKSUM_MISMATCH_MESSAGE0_UPLOAD_METADATA_NO_APPROPRIATE_CHECKSUM_MESSAGEc                   x    e Zd ZdZd	dZed             Zd Zed             Z	ed             Z
ed             ZdS )

UploadBasea  Base class for upload helpers.

    Defines core shared behavior across different upload types.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    Nc                 h    || _         |i }|| _        d| _        t          j                    | _        d S )NF)
upload_url_headers	_finishedr   RetryStrategy_retry_strategy)selfr   headerss      t/home/panchajanya/Development/work/volatility3/lib/python3.11/site-packages/google/_async_resumable_media/_upload.py__init__zUploadBase.__init__F   s8    $?G%355    c                     | j         S )z2bool: Flag indicating if the upload has completed.)r   r   s    r    finishedzUploadBase.finishedN   s     ~r"   c                 j    d| _         t          j        |t          j        j        f| j                   dS )a  Process the response from an HTTP request.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 200.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        TN)r   r   require_status_codehttpclientOK_get_status_coder   responses     r    _process_responsezUploadBase._process_responseS   s0    $ $X/@$BWXXXXXr"   c                      t          d          )zAccess the status code from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        This implementation is virtual.NotImplementedErrorr-   s    r    r+   zUploadBase._get_status_codeh        ""CDDDr"   c                      t          d          )zAccess the headers from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   r3   s    r    _get_headerszUploadBase._get_headerst   r4   r"   c                      t          d          )zAccess the response body from an HTTP response.

        Args:
            response (object): The HTTP response object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   r3   s    r    	_get_bodyzUploadBase._get_body   r4   r"   N)__name__
__module____qualname____doc__r!   propertyr%   r.   staticmethodr+   r6   r8    r"   r    r   r   8   s         6 6 6 6   XY Y Y* 	E 	E \	E 	E 	E \	E 	E 	E \	E 	E 	Er"   r   c                        e Zd ZdZd ZddZdS )SimpleUploada  Upload a resource to a Google API.

    A **simple** media upload sends no metadata and completes the upload
    in a single request.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    c                     | j         rt          d          t          |t                    st	          dt          |                    || j        t          <   t          | j	        || j        fS )a  Prepare the contents of an HTTP request.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        .. note:

            This method will be used only once, so ``headers`` will be
            mutated by having a new key added to it.

        Args:
            data (bytes): The resource content to be uploaded.
            content_type (str): The content type for the request.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already finished.
            TypeError: If ``data`` isn't bytes.

        .. _sans-I/O: https://sans-io.readthedocs.io/
         An upload can only be used once.`data` must be bytes, received)
r%   
ValueError
isinstancebytes	TypeErrortyper   r   r   r   )r   datacontent_types      r    _prepare_requestzSimpleUpload._prepare_request   sh    < = 	A?@@@$&& 	J<d4jjIII.:*+dotT]::r"   Nc                      t          d          )a  Transmit the resource to be uploaded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            data (bytes): The resource content to be uploaded.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   	transportrK   rL   timeouts        r    transmitzSimpleUpload.transmit   s    $ ""CDDDr"   r9   )r:   r;   r<   r=   rM   rQ   r@   r"   r    rB   rB      sH         $; $; $;LE E E E E Er"   rB   c                   2     e Zd ZdZd fd	Zd ZddZ xZS )MultipartUploada3  Upload a resource with metadata to a Google API.

    A **multipart** upload sends both metadata and the resource in a single
    (multipart) request.

    Args:
        upload_url (str): The URL where the content will be uploaded.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the request, e.g. headers for encrypted data.
        checksum Optional([str]): The type of checksum to compute to verify
            the integrity of the object. The request metadata will be amended
            to include the computed value. Using this option will override a
            manually-set checksum value. Supported values are "md5", "crc32c"
            and None. The default is None.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.
    Nc                 j    t          t          |                               ||           || _        d S )Nr   )superrS   r!   _checksum_type)r   r   r   checksum	__class__s       r    r!   zMultipartUpload.__init__   s4    ot$$--j'-JJJ&r"   c                    | j         rt          d          t          |t                    st	          dt          |                    t          j        | j                  }|Y|	                    |           t          j
        |                                          }t          j        | j                  }|||<   t          |||          \  }}t          |z   dz   }	|	| j        t           <   t"          | j        || j        fS )aj  Prepare the contents of an HTTP request.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        .. note:

            This method will be used only once, so ``headers`` will be
            mutated by having a new key added to it.

        Args:
            data (bytes): The resource content to be uploaded.
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already finished.
            TypeError: If ``data`` isn't bytes.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        rD   rE   N   ")r%   rF   rG   rH   rI   rJ   sync_helpers_get_checksum_objectrW   updateprepare_checksum_digestdigest_get_metadata_keyconstruct_multipart_requestr   r   r   r   r   )
r   rK   metadatarL   checksum_objectactual_checksummetadata_keycontentmultipart_boundarymultipart_content_types
             r    rM   z MultipartUpload._prepare_request   s   B = 	A?@@@$&& 	J<d4jjIII&;D<OPP&""4(((*B&&(( O (9$:MNNL%4H\"&A(L'
 '
## "13E!E!L.D*+dow==r"   c                      t          d          )aq  Transmit the resource to be uploaded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            data (bytes): The resource content to be uploaded.
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   rK   rc   rL   rP   s         r    rQ   zMultipartUpload.transmit)      ( ""CDDDr"   NNr9   )r:   r;   r<   r=   r!   rM   rQ   __classcell__rY   s   @r    rS   rS      ss         &' ' ' ' ' '8> 8> 8>tE E E E E E E Er"   rS   c                        e Zd ZdZd fd	Zed             Zed             Zed             Zed             Z	ed             Z
	 dd
Zd Z	 	 	 ddZd Zd Zd Zd ZddZd Zd Zd Z xZS )ResumableUploada  Initiate and fulfill a resumable upload to a Google API.

    A **resumable** upload sends an initial request with the resource metadata
    and then gets assigned an upload ID / upload URL to send bytes to.
    Using the upload URL, the upload is then done in chunks (determined by
    the user) until all bytes have been uploaded.

    Args:
        upload_url (str): The URL where the resumable upload will be initiated.
        chunk_size (int): The size of each chunk used to upload the resource.
        headers (Optional[Mapping[str, str]]): Extra headers that should
            be sent with the :meth:`initiate` request, e.g. headers for
            encrypted data. These **will not** be sent with
            :meth:`transmit_next_chunk` or :meth:`recover` requests.
        checksum Optional([str]): The type of checksum to compute to verify
            the integrity of the object. After the upload is complete, the
            server-computed checksum of the resulting object will be read
            and google.resumable_media.common.DataCorruption will be raised on
            a mismatch. The corrupted file will not be deleted from the remote
            host automatically. Supported values are "md5", "crc32c" and None.
            The default is None.

    Attributes:
        upload_url (str): The URL where the content will be uploaded.

    Raises:
        ValueError: If ``chunk_size`` is not a multiple of
            :data:`.UPLOAD_CHUNK_SIZE`.
    Nc                 l   t          t          |                               ||           |t          j        z  dk    r/t          d                    t          j        dz                      || _        d | _        d | _	        d| _
        d| _        || _        d | _        d | _        d | _        d| _        d S )NrU   r   z{} KB must divide chunk sizei   F)rV   rp   r!   r   UPLOAD_CHUNK_SIZErF   format_chunk_size_stream_content_type_bytes_uploaded_bytes_checksummedrW   _checksum_object_total_bytes_resumable_url_invalid)r   r   
chunk_sizerX   r   rY   s        r    r!   zResumableUpload.__init___  s    ot$$--j'-JJJ.@@AEE.55*<tC   
 &! "#& $ "r"   c                     | j         S )zbool: Indicates if the upload is in an invalid state.

        This will occur if a call to :meth:`transmit_next_chunk` fails.
        To recover from such a failure, call :meth:`recover`.
        r|   r$   s    r    invalidzResumableUpload.invalidr  s     }r"   c                     | j         S )z8int: The size of each chunk used to upload the resource.)rt   r$   s    r    r}   zResumableUpload.chunk_size{  s     r"   c                     | j         S )z;Optional[str]: The URL of the in-progress resumable upload.)r{   r$   s    r    resumable_urlzResumableUpload.resumable_url  s     ""r"   c                     | j         S )z-int: Number of bytes that have been uploaded.)rw   r$   s    r    bytes_uploadedzResumableUpload.bytes_uploaded  s     ##r"   c                     | j         S )a  Optional[int]: The total number of bytes to be uploaded.

        If this upload is initiated (via :meth:`initiate`) with
        ``stream_final=True``, this value will be populated based on the size
        of the ``stream`` being uploaded. (By default ``stream_final=True``.)

        If this upload is initiated with ``stream_final=False``,
        :attr:`total_bytes` will be :data:`None` since it cannot be
        determined from the stream.
        )rz   r$   s    r    total_byteszResumableUpload.total_bytes  s       r"   Tc                    | j         t          d          |                                dk    rt          d          || _        || _        t
          dd|i}||| _        n|rt          |          | _        | j        d                    | j                  }||d<   |	                    | j
                   t          j        |                              d	          }t          | j        ||fS )
a  Prepare the contents of HTTP request to initiate upload.

        This is everything that must be done before a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            stream (IO[bytes]): The stream (i.e. file-like object) that will
                be uploaded. The stream **must** be at the beginning (i.e.
                ``stream.tell() == 0``).
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            total_bytes (Optional[int]): The total number of bytes to be
                uploaded. If specified, the upload size **will not** be
                determined from the stream (even if ``stream_final=True``).
            stream_final (Optional[bool]): Indicates if the ``stream`` is
                "final" (i.e. no more bytes will be added to it). In this case
                we determine the upload size from the size of the stream. If
                ``total_bytes`` is passed, this argument will be ignored.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always POST)
              * the URL for the request
              * the body of the request
              * headers for the request

        Raises:
            ValueError: If the current upload has already been initiated.
            ValueError: If ``stream`` is not at the beginning.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        Nz'This upload has already been initiated.r   zStream must be at beginning.zapplication/json; charset=UTF-8zx-upload-content-typez{:d}zx-upload-content-lengthutf-8)r   rF   tellru   rv   r   rz   get_total_bytesrs   r^   r   jsondumpsencoder   r   )	r   streamrc   rL   r   stream_finalr   content_lengthpayloads	            r    _prepare_initiate_requestz)ResumableUpload._prepare_initiate_request  s    N )FGGG;;==A;<<<) "C#\

 " +D 	8 / 7 7D(#]]4+<==N1?G-.t}%%%*X&&--g66dow77r"   c                     t          j        |t          j        j        f| j        | j                   t          j        |d| j                  | _	        dS )aV  Process the response from an HTTP request that initiated upload.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        This method takes the URL from the ``Location`` header and stores it
        for future use. Within that URL, we assume the ``upload_id`` query
        parameter has been included, but we do not check.

        Args:
            response (object): The HTTP response object (need headers).

        .. _sans-I/O: https://sans-io.readthedocs.io/
        callbacklocationN)
r   r'   r(   r)   r*   r+   _make_invalidheader_requiredr6   r{   r,   s     r    _process_initiate_responsez*ResumableUpload._process_initiate_response  s^      	$[^!'		
 	
 	
 	
 '6j$"3
 
r"   c                      t          d          )ah  Initiate a resumable upload.

        By default, this method assumes your ``stream`` is in a "final"
        state ready to transmit. However, ``stream_final=False`` can be used
        to indicate that the size of the resource is not known. This can happen
        if bytes are being dynamically fed into ``stream``, e.g. if the stream
        is attached to application logs.

        If ``stream_final=False`` is used, :attr:`chunk_size` bytes will be
        read from the stream every time :meth:`transmit_next_chunk` is called.
        If one of those reads produces strictly fewer bites than the chunk
        size, the upload will be concluded.

        Args:
            transport (object): An object which can make authenticated
                requests.
            stream (IO[bytes]): The stream (i.e. file-like object) that will
                be uploaded. The stream **must** be at the beginning (i.e.
                ``stream.tell() == 0``).
            metadata (Mapping[str, str]): The resource metadata, such as an
                ACL list.
            content_type (str): The content type of the resource, e.g. a JPEG
                image has content type ``image/jpeg``.
            total_bytes (Optional[int]): The total number of bytes to be
                uploaded. If specified, the upload size **will not** be
                determined from the stream (even if ``stream_final=True``).
            stream_final (Optional[bool]): Indicates if the ``stream`` is
                "final" (i.e. no more bytes will be added to it). In this case
                we determine the upload size from the size of the stream. If
                ``total_bytes`` is passed, this argument will be ignored.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   r   rc   rL   r   r   rP   s           r    initiatezResumableUpload.initiate  s    b ""CDDDr"   c                    | j         rt          d          | j        rt          d          | j        t          d          t	          | j        | j        | j                  \  }}}|| j        k    r)t          j
        || j                  }t          |          |                     ||           t          | j        t          j        |i}t           | j        ||fS )a  Prepare the contents of HTTP request to upload a chunk.

        This is everything that must be done before a request that doesn't
        require network I/O. This is based on the `sans-I/O`_ philosophy.

        For the time being, this **does require** some form of I/O to read
        a chunk from ``stream`` (via :func:`get_next_chunk`). However, this
        will (almost) certainly not be network I/O.

        Returns:
            Tuple[str, str, bytes, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always PUT)
              * the URL for the request
              * the body of the request
              * headers for the request

            The headers **do not** incorporate the ``_headers`` on the
            current instance.

        Raises:
            ValueError: If the current upload has finished.
            ValueError: If the current upload is in an invalid state.
            ValueError: If the current upload has not been initiated.
            ValueError: If the location in the stream (i.e. ``stream.tell()``)
                does not agree with ``bytes_uploaded``.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        zUpload has finished.z;Upload is in an invalid state. To recover call `recover()`.Nz_This upload has not been initiated. Please call initiate() before beginning to transmit chunks.)r%   rF   r   r   get_next_chunkru   rt   rz   r   r   rs   _update_checksumr   rv   r   CONTENT_RANGE_HEADERr   )r   
start_byter   content_rangemsgr   s         r    rM   z ResumableUpload._prepare_request%  s    < = 	53444< 	M   %B  
 .<L$*D,=.
 .
*
G] ,,,(/
D<OPPCS//!j'222 !$"4)=
 T''99r"   c                     d| _         dS )zSimple setter for ``invalid``.

        This is intended to be passed along as a callback to helpers that
        raise an exception so they can mark this instance as invalid before
        raising.
        TNr   r$   s    r    r   zResumableUpload._make_invalid^  s     r"   c                 L  K   t          j        |t          j        j        t          j        j        f| j        | j                  }|t          j        j        k    r3| j        |z   | _        d| _	        | 
                    |           d{V  dS t          j        |t           j        | j        | j                  }t          j        |          }|+|                                  t!          j        |d|d          t%          |                    d                    dz   | _        dS )a  Process the response from an HTTP request.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.
            bytes_sent (int): The number of bytes sent in the request that
                ``response`` was returned for.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is 308 and the ``range`` header is not of the form
                ``bytes 0-{end}``.
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 200 or 308.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        r   TNUnexpected "range" header*Expected to be of the form "bytes=0-{end}"end_byte   )r   r'   r(   r)   r*   PERMANENT_REDIRECTr+   r   rw   r   _validate_checksumr   RANGE_HEADERr6   r   matchr   InvalidResponseintgroup)r   r-   
bytes_sentstatus_codebytes_ranger   s         r    _process_resumable_responsez+ResumableUpload._process_resumable_responseg  s4     * 2[^T[;<!'	
 
 
 $+.(( $(#7*#DD !DN))(33333333333"2%!+	  K $)+66E}""$$$,/@	   $'u{{:'>'>#?#?!#CD   r"   c                   K   | j         dS t          j        | j                   }|                                 d{V }|                    |          }|;t          j        |t          j        |          | 	                    |                    t          j
        | j                                                  }||k    r@t          j        |t          j        | j                                         ||                    dS )aQ  Check the computed checksum, if any, against the response headers.
        Args:
            response (object): The HTTP response object.
        Raises:
            ~google.resumable_media.common.DataCorruption: If the checksum
            computed locally and the checksum reported by the remote host do
            not match.
        N)rW   r\   ra   r   getr   r   r   rs   r6   r_   ry   r`   DataCorruptionr   upper)r   r-   rf   rc   remote_checksumlocal_checksums         r    r   z"ResumableUpload._validate_checksum  s      &F#5d6IJJ!((((((",,|44"(@GUU!!(++  
 &=!((**
 
 _,,'18'--//    -,r"   c                      t          d          )a  Transmit the next chunk of the resource to be uploaded.

        If the current upload was initiated with ``stream_final=False``,
        this method will dynamically determine if the upload has completed.
        The upload will be considered complete if the stream produces
        fewer than :attr:`chunk_size` bytes when a chunk is read from it.

        Args:
            transport (object): An object which can make authenticated
                requests.
            timeout (Optional[Union[float, aiohttp.ClientTimeout]]):
                The number of seconds to wait for the server response.
                Depending on the retry strategy, a request may be repeated
                several times using the same timeout each time.
                Can also be passed as an `aiohttp.ClientTimeout` object.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   rP   s      r    transmit_next_chunkz#ResumableUpload.transmit_next_chunk  rk   r"   c                 j    | j         st          d          t          j        di}t          | j        d|fS )a  Prepare the contents of HTTP request to recover from failure.

        This is everything that must be done before a request that doesn't
        require network I/O. This is based on the `sans-I/O`_ philosophy.

        We assume that the :attr:`resumable_url` is set (i.e. the only way
        the upload can end up :attr:`invalid` is if it has been initiated.

        Returns:
            Tuple[str, str, NoneType, Mapping[str, str]]: The quadruple

              * HTTP verb for the request (always PUT)
              * the URL for the request
              * the body of the request (always :data:`None`)
              * headers for the request

            The headers **do not** incorporate the ``_headers`` on the
            current instance.

        Raises:
            ValueError: If the current upload is not in an invalid state.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        z3Upload is not in invalid state, no need to recover.z	bytes */*N)r   rF   r   r   r   r   )r   r   s     r    _prepare_recover_requestz(ResumableUpload._prepare_recover_request  s=    2 | 	TRSSS0+>T'w66r"   c                    t          j        |t          j        j        f| j                   |                     |          }t           j        |v rj|t           j                 }t          j	        |          }|t          j        |d|d          t          |                    d                    dz   | _        nd| _        | j                            | j                   d| _        dS )a  Process the response from an HTTP request to recover from failure.

        This is everything that must be done after a request that doesn't
        require network I/O (or other I/O). This is based on the `sans-I/O`_
        philosophy.

        Args:
            response (object): The HTTP response object.

        Raises:
            ~google.resumable_media.common.InvalidResponse: If the status
                code is not 308.
            ~google.resumable_media.common.InvalidResponse: If the status
                code is 308 and the ``range`` header is not of the form
                ``bytes 0-{end}``.

        .. _sans-I/O: https://sans-io.readthedocs.io/
        Nr   r   r   r   r   F)r   r'   r(   r)   r   r+   r6   r   r   r   r   r   r   r   rw   ru   seekr|   )r   r-   r   r   r   s        r    _process_recover_responsez)ResumableUpload._process_recover_response  s    & 	$[+-!	
 	
 	

 ##H-- G++!("78K#)+66E},/@	   $'u{{:'>'>#?#?!#CD   $%D $.///r"   c                      t          d          )a!  Recover from a failure.

        This method should be used when a :class:`ResumableUpload` is in an
        :attr:`~ResumableUpload.invalid` state due to a request failure.

        This will verify the progress with the server and make sure the
        current upload is in a valid state before :meth:`transmit_next_chunk`
        can be used again.

        Args:
            transport (object): An object which can make authenticated
                requests.

        Raises:
            NotImplementedError: Always, since virtual.
        r0   r1   )r   rO   s     r    recoverzResumableUpload.recover!  s    " ""CDDDr"   rl   )NT)NTNr9   )r:   r;   r<   r=   r!   r>   r   r}   r   r   r   r   r   r   rM   r   r   r   r   r   r   r   rm   rn   s   @r    rp   rp   @  s        <     &   X     X  # # X# $ $ X$ ! ! X! NR>8 >8 >8 >8@
 
 
@ 1E 1E 1E 1Ef7: 7: 7:r  9D 9D 9Dv  >E E E E,7 7 7>) ) )VE E E E E E Er"   rp   c                      t          j        t          j                  } t	          j        |           }|                    d          S )zGet a random boundary for a multipart request.

    Returns:
        bytes: The boundary used to separate parts of a multipart request.
    r   )random	randrangesysmaxsizer   rs   r   )
random_intboundarys     r    get_boundaryr   5  s:     !#+..J&z22H ??7###r"   c                 J   t                      }t          j        |                              d          }|                    d          }t          |z   }|t
          z   |z   t          z   |z   t          z   dz   |z   t          z   t          z   | z   t          z   |z   t          z   }||fS )a  Construct a multipart request body.

    Args:
        data (bytes): The resource content (UTF-8 encoded as bytes)
            to be uploaded.
        metadata (Mapping[str, str]): The resource metadata, such as an
            ACL list.
        content_type (str): The content type of the resource, e.g. a JPEG
            image has content type ``image/jpeg``.

    Returns:
        Tuple[bytes, bytes]: The multipart request body and the boundary used
        between each part.
    r   s   content-type: )r   r   r   r   r   r   r   )rK   rc   rL   rh   
json_bytesboundary_seprg   s          r    rb   rb   B  s     &H%%,,W55J&&w//L "$66L
	
	 	 		
 	 	 	 	 		 
	 	 	 	 " &&&r"   c                     |                                  }|                     dt          j                   |                                  }|                     |           |S )zDetermine the total number of bytes in a stream.

    Args:
       stream (IO[bytes]): The stream (i.e. file-like object).

    Returns:
        int: The number of bytes.
    r   )r   r   osSEEK_END)r   current_positionend_positions      r    r   r   k  sP     {{}} KK2;;;==L
KK !!!r"   c                    |                                  }|,||z   |cxk    rdk    rn n|                     ||z
            }n|                     |          }|                                  dz
  }t          |          }|||k     r|dz   }n1|dk    r|dk    rt          d          n|dk    rt          d          t	          |||          }|||fS )a  Get a chunk from an I/O stream.

    The ``stream`` may have fewer bytes remaining than ``chunk_size``
    so it may not always be the case that
    ``end_byte == start_byte + chunk_size - 1``.

    Args:
        stream (IO[bytes]): The stream (i.e. file-like object).
        chunk_size (int): The size of the chunk to be read from the ``stream``.
        total_bytes (Optional[int]): The (expected) total number of bytes
            in the ``stream``.

    Returns:
        Tuple[int, bytes, str]: Triple of:

          * the start byte index
          * the content in between the start and end bytes (inclusive)
          * content range header for the chunk (slice) that has been read

    Raises:
        ValueError: If ``total_bytes == 0`` but ``stream.read()`` yields
            non-empty content.
        ValueError: If there is no data left to consume. This corresponds
            exactly to the case ``end_byte < start_byte``, which can only
            occur if ``end_byte == start_byte - 1``.
    Nr   r   z:Stream specified as empty, but produced non-empty content.z;Stream is already exhausted. There is no content remaining.)r   readlenrF   get_content_range)r   r}   r   r   r   r   num_bytes_readr   s           r    r   r     s   6 J:
#:k#M#M#M#MA#M#M#M#M#M++kJ677++j)){{}}q H\\NJ&&"Q,K			 QL   
 QM   &j(KHHMw--r"   c                     |t          j        | |          S || k     rt          j        |          S t          j        | ||          S )a  Convert start, end and total into content range header.

    If ``total_bytes`` is not known, uses "bytes {start}-{end}/*".
    If we are dealing with an empty range (i.e. ``end_byte < start_byte``)
    then "bytes */{total}" is used.

    This function **ASSUMES** that if the size is not known, the caller will
    not also pass an empty range.

    Args:
        start_byte (int): The start (inclusive) of the byte range.
        end_byte (int): The end (inclusive) of the byte range.
        total_bytes (Optional[int]): The number of bytes in the byte
            range (if known).

    Returns:
        str: The content range header.
    )r	   rs   r
   r   )r   r   r   s      r    r   r     sN    & &-j(CCC	J		$+K888&-j(KPPPr"   )*r=   http.clientr(   r   r   r   r   googler   google._async_resumable_mediar   google.resumable_mediar\   r   sync_uploadr   google.resumable_media._uploadr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   objectr   rB   rS   rp   r   rb   r   r   r   r@   r"   r    <module>r      s         				  



 ) ) ) ) ) ) 2 2 2 2 2 2 ; ; ; ; ; ; 9 9 9 9 9 9 ) ) ) ) ) )                                 &RE RE RE RE RE RE RE REjGE GE GE GE GE: GE GE GETfE fE fE fE fEj fE fE fERrE rE rE rE rEj+"= rE rE rEj
$ 
$ 
$&' &' &'R  (6. 6. 6.rQ Q Q Q Qr"   