a
    hu                     @   s@   d Z ddlZddlZddlmZ ddlmZ G dd deZdS )zGit LFS related utilities    N)AbstractContextManager)BinaryIOc                   @   sp   e Zd ZdZeeedddZdd Zdd Zded
ddZ	edddZ
ejfeeedddZdd ZdS )SliceFileObja  
    Utility context manager to read a *slice* of a seekable file-like object as a seekable, file-like object.

    This is NOT thread safe

    Inspired by stackoverflow.com/a/29838711/593036

    Credits to @julien-c

    Args:
        fileobj (`BinaryIO`):
            A file-like object to slice. MUST implement `tell()` and `seek()` (and `read()` of course).
            `fileobj` will be reset to its original position when exiting the context manager.
        seek_from (`int`):
            The start of the slice (offset from position 0 in bytes).
        read_limit (`int`):
            The maximum number of bytes to read from the slice.

    Attributes:
        previous_position (`int`):
            The previous position

    Examples:

    Reading 200 bytes with an offset of 128 bytes from a file (ie bytes 128 to 327):
    ```python
    >>> with open("path/to/file", "rb") as file:
    ...     with SliceFileObj(file, seek_from=128, read_limit=200) as fslice:
    ...         fslice.read(...)
    ```

    Reading a file in chunks of 512 bytes
    ```python
    >>> import os
    >>> chunk_size = 512
    >>> file_size = os.getsize("path/to/file")
    >>> with open("path/to/file", "rb") as file:
    ...     for chunk_idx in range(ceil(file_size / chunk_size)):
    ...         with SliceFileObj(file, seek_from=chunk_idx * chunk_size, read_limit=chunk_size) as fslice:
    ...             chunk = fslice.read(...)

    ```
    fileobj	seek_from
read_limitc                 C   s   || _ || _|| _d S Nr   )selfr   r   r    r   V/var/www/html/assistant/venv/lib/python3.9/site-packages/huggingface_hub/utils/_lfs.py__init__D   s    zSliceFileObj.__init__c                 C   sF   | j  | _| j dtj}t| j|| j | _	| j | jt
j | S )Nr   )r   tell_previous_positionseekosSEEK_ENDminr   r   _lenioSEEK_SET)r
   Zend_of_streamr   r   r   	__enter__I   s
    zSliceFileObj.__enter__c                 C   s   | j | jtj d S r	   )r   r   r   r   r   )r
   exc_type	exc_value	tracebackr   r   r   __exit__Q   s    zSliceFileObj.__exit__nc                 C   sB   |   }|| jkrdS | j| }| j|dk r2|nt||}|S )N    r   )r   r   r   readr   )r
   r   posZremaining_amountdatar   r   r   r    T   s    

zSliceFileObj.read)returnc                 C   s   | j  | j S r	   )r   r   r   r
   r   r   r   r   \   s    zSliceFileObj.tell)offsetwhencer#   c                 C   s   | j }|| j }|tjtjfv rR|tjkr2|| n|| }t|t||}tj}n>|tjkr| j	 }t|| t||| }nt
d| d| j||| j  S )Nzwhence value z is not supported)r   r   r   r   r   maxr   SEEK_CURr   r   
ValueErrorr   )r
   r%   r&   startendZcur_posr   r   r   r   _   s    


zSliceFileObj.seekc                 c   s   | j ddV  d S )Ni  @ r   )r    r$   r   r   r   __iter__m   s    zSliceFileObj.__iter__N)r   )__name__
__module____qualname____doc__r   intr   r   r   r    r   r   r   r   r,   r   r   r   r   r      s   ,r   )r0   r   r   
contextlibr   typingr   r   r   r   r   r   <module>   s
   