
    gk                     ^   d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZ d dlmZmZmZmZmZ d dlmZmZ d dlmZ dZ	 d dlmZ d	Zd
Z G d de      Z G d de      Z G d d      Z G d de      Z  G d de      Z! G d de      Z" G d d      Z# G d d      Z$y# e$ r Y _w xY w)    )BytesION)msb_sizestream_copyapply_delta_dataconnect_deltasdelta_types)allocate_memory	LazyMixinmake_shawriteclose)	NULL_BYTE
BYTE_SPACE)force_bytesF)apply_deltaT)	DecompressMemMapReaderFDCompressedSha1WriterDeltaApplyReader
Sha1WriterFlexibleSha1WriterZippedStoreShaWriterr   FDStream
NullStreamc                   x    e Zd ZdZdZdZddZd Zd Zd Z	e
dd	       Zd
 Zd Zd Z eedd      fdZddZy)r   a  Reads data in chunks from a memory map and decompresses it. The client sees
    only the uncompressed data, respective file-like read calls are handling on-demand
    buffered decompression accordingly

    A constraint on the total size of bytes is activated, simulating
    a logical file within a possibly larger physical memory area

    To read efficiently, you clearly don't want to read individual bytes, instead,
    read a few kilobytes at least.

    **Note:** The chunk-size should be carefully selected as it will involve quite a bit
        of string copying due to the way the zlib is implemented. Its very wasteful,
        hence we try to find a good tradeoff between allocation time and number of
        times we actually allocate. An own zlib implementation would be good here
        to better support streamed reading - it would only need to keep the mmap
        and decompress it into chunks, that's all ... )_m_zip_buf_buflen_br_cws_cwe_s_close_cbr_phii   Nc                     || _         t        j                         | _        d| _        d| _        ||| _        d| _        d| _        d| _	        d| _
        d| _        || _        y)z|Initialize with mmap for stream reading
        :param m: must be content data - use new if you have object data and no sizeNr   F)r   zlibdecompressobjr   r   r   r"   r   r    r!   r$   r%   r#   )selfmclose_on_deletionsizes       A/var/www/openai/venv/lib/python3.12/site-packages/gitdb/stream.py__init__zDecompressMemMapReader.__init__E   s`     &&(		DG				'    c                 2    |dk(  sJ | j                          y )Nr"   )_parse_header_infor)   attrs     r-   _set_cache_z"DecompressMemMapReader._set_cache_U   s    t|| 	!r/   c                 $    | j                          y N)r   r)   s    r-   __del__zDecompressMemMapReader.__del__[   s    

r/   c                 4   d}|| _         | j                  |      }|j                  t              }|d| j	                  t
              \  }}t        |      }|| _         d| _        |dz  }t        ||d       | _	        t        |      |z
  | _        d| _        ||fS )zIf this stream contains object data, parse the header info and skip the
        stream to a point where each read will yield object content

        :return: parsed type_string, sizei    Nr      T)r"   readfindr   splitr   intr   r   r   lenr   r%   )r)   maxbhdrhdrendtypr,   s         r-   r1   z)DecompressMemMapReader._parse_header_info^   s     iio)$L&&z2	T4y !CL)	3x&(	Dyr/   c                 L    t        ||d      }|j                         \  }}|||fS )a  Create a new DecompressMemMapReader instance for acting as a read-only stream
        This method parses the object header from m and returns the parsed
        type and size, as well as the created stream instance.

        :param m: memory map on which to operate. It must be object data ( header + contents )
        :param close_on_deletion: if True, the memory map will be closed once we are
            being deletedr   )r   r1   )r)   r*   r+   instrC   r,   s         r-   newzDecompressMemMapReader.new{   s1     &a):A>++-	TD$r/   c                     | j                   S )z8:return: random access compatible data we are working on)r   r7   s    r-   datazDecompressMemMapReader.data   s    wwr/   c                     | j                   r8t        | j                  d      r| j                  j                          d| _         yy)zClose our underlying stream of compressed bytes if this was allowed during initialization
        :return: True if we closed the underlying stream
        :note: can be called safely
        r   FN)r#   hasattrr   r   r7   s    r-   r   zDecompressMemMapReader.close   s2    
 ;;tww(DK r/   c                    | j                   | j                  k(  rD| j                  j                  s-d| _         t	        | j                  d      ro| j                  j
                  t        j                  k(  r| j                  t        j                         | j                  j
                  t        j                  k(  rGn| j                  j                  sz| j                  t        | j                        k7  rX| j                  t        j                         | j                  j                  s#| j                  t        | j                        k7  rX| j                  | _         | j                  S )z
        :return: number of compressed bytes read. This includes the bytes it
            took to decompress the header ( if there was one )r   status)r   r"   r   unused_datarJ   rL   r'   Z_OKr;   mmapPAGESIZEr$   r?   r   r7   s    r-   compressed_bytes_readz,DecompressMemMapReader.compressed_bytes_read   s    0 88twwtyy'<'< DHtyy(+ii&&$))3IIdmm, ii&&$))3
 ))//DIITWW4MIIdmm, ))//DIITWW4M wwDH
 yyr/   SEEK_SETr   c                     |dk7  s|t        t        dd      k7  rt        d      t        j                         | _        dx| _        x| _        x| _        | _	        | j                  r
d| _
        | `yy)zgAllows to reset the stream to restart reading
        :raise ValueError: If offset and whence are not 0r   rR   Can only seek to position 0FN)getattros
ValueErrorr'   r(   r   r   r    r!   r$   r%   r"   r)   offsetwhences      r-   seekzDecompressMemMapReader.seek   sm     Q;&GB
A$>>:;; &&(	7888498ty4999DI r/   c                 `   |dk  r| j                   | j                  z
  }n#t        || j                   | j                  z
        }|dk(  ryd}| j                  r| j                  |k\  rG| j                  j                  |      }| xj                  |z  c_        | xj                  |z  c_        |S | j                  j                         }|| j                  z  }| xj                  | j                  z  c_        d| _        d | _        | j                  j                  }|r2| j                  t        |      z
  | _
        | j                  |z   | _        n'| j                  }| j                  | _
        ||z   | _        | j                  | j                  z
  dk  r| j                  dz   | _        | j                  | j                  | j                   }| j                  t        |      z   | _        | j                  j                  ||      }t        t        dt        j                        dv r3t         j"                  dk(  s t        | j                  j                        }n?t        | j                  j                        t        | j                  j$                        z   }| xj&                  t        |      |z
  z  c_        | xj                  t        |      z  c_        |r||z   }|rSt        |      t        |      z
  |k  r9| j                  | j                   k  r || j                  |t        |      z
        z  }|S )Nr:   r   r/      ZLIB_RUNTIME_VERSION)z1.2.7z1.2.5darwin)r"   r   minr   r   r;   r   unconsumed_tailr!   r?   r    r   
decompressrU   r'   ZLIB_VERSIONsysplatformrM   r$   )r)   r,   dattailcwsindatadcompdatunused_datalens           r-   r;   zDecompressMemMapReader.read   sv   !877TXX%DtTWWtxx/0D 19 99||t#iinnT*$D 
iinn&$DLL(  	 yy(( 		CI-DI		D(DI))C		DId
DI 99tyy 1$		ADI 499- IIF+	99''5 4/1B1BCGYYbebnbnrzbz !:!:;N !:!:;c$))BWBW>XXN 			S[>11	CM!X~H XS1T9dhh>P		$X"677Hr/   r6   F))__name__
__module____qualname____doc__	__slots__max_read_sizer.   r4   r8   r1   classmethodrF   rH   r   rQ   rU   rV   r[   r;    r/   r-   r   r   .   sf    : !I M( ": 
 
 -b #*"j!"< ir/   r   c                       e Zd ZdZdZdZd Zd Zd Ze	seZ
neZ
ddZ eed	d      fd
Zed        Zed        Zed        Zed        Zy)r   a  A reader which dynamically applies pack deltas to a base object, keeping the
    memory demands to a minimum.

    The size of the final object is only obtainable once all deltas have been
    applied, unless it is retrieved from a pack index.

    The uncompressed Delta has the following layout (MSB being a most significant
    bit encoded dynamic size):

    * MSB Source Size - the size of the base against which the delta was created
    * MSB Target Size - the size of the resulting data after the delta was applied
    * A list of one byte commands (cmd) which are followed by a specific protocol:

     * cmd & 0x80 - copy delta_data[offset:offset+size]

      * Followed by an encoded offset into the delta data
      * Followed by an encoded size of the chunk to copy

     *  cmd & 0x7f - insert

      * insert cmd bytes from the delta buffer into the output stream

     * cmd == 0 - invalid operation ( or error in delta stream )
    )_bstream	_dstreams
_mm_target_sizer   ic                 v    t        |      dkD  sJ d       |d   | _        t        |dd       | _        d| _        y)zInitialize this instance with a list of streams, the first stream being
        the delta to apply on top of all following deltas, the last stream being the
        base object onto which to apply the deltasr:   z+Need at least one delta and one base streamrm   Nr   )r?   rw   tuplerx   r   )r)   stream_lists     r-   r.   zDeltaApplyReader.__init__h  sB     ;!#R%RR##B{3B/0r/   c                    t        | j                        dk(  r| j                  |      S t        | j                        }|j	                         dk(  rd| _        t        d      | _        y |j	                         | _        t        | j
                        | _        t        | j                  j                        }t        | j                  j                  |j                  | j                  j                  dt        j                  z         | j                  j                  }|j                  ||       | j                  j!                  d       y )Nr:   r      )r?   rx   _set_cache_brute_r   rboundrz   r	   ry   rw   r,   r   r;   r   rO   rP   applyr[   )r)   r3   dclbbufr   s        r-   _set_cache_too_slow_without_cz.DeltaApplyReader._set_cache_too_slow_without_cr  s     t~~!#))$//
 T^^, ::<1DJ-a0DO ZZ\
)$**5t}}112DMM&&

DMM4F4FdmmH[\ %%		$Qr/   c           	      "   t               }d}| j                  D ]T  }|j                  d      }t        |      \  }}t        ||      \  }}|j	                  ||d |||f       t        ||      }V | j                  j                  }	|}t        | j                        dkD  rt        |	|      x}	}t        |	      }
t        | j                  j                  |
j                  |	dt        j                  z         t        |      }d}t        t        |      t        | j                              D ]  \  \  }}}}}t        |j                  |z
        }|j                  |       t        |j                  |j                  |j                  dt        j                  z         dt!               v rt#        |
||       n"t%        |
||t        |      |j                         ||
}}
|
j'                  d       |j'                  d       |} |
| _        || _        y)z*If we are here, we apply the actual deltasr   i   Nr:   r   c_apply_delta)listrx   r;   r   appendmaxrw   r,   r?   r	   r   r   rO   rP   zipreversedglobalsr   r   r[   ry   rz   )r)   r3   buffer_info_listmax_target_sizedstreambufrY   src_sizetarget_size	base_sizer   tbuffinal_target_sizedbufddatas                  r-   r   z"DeltaApplyReader._set_cache_brute_  s   
  6~~G,,s#C'}FH"*3"7FK##S\68[$QR!/;?O & MM&&	% t~~"&))_&EEI
 y)DMM&&

IsT]]?RS {+ !>A(K[B\^fgkgugu^v>w:1T68[7 $GLL6$9:EKKekk7<<t}}ATU ')+dE40 xE
DJJO
 t$DIIaLIIaL +/ ?x: &
r/   r   c                     | j                   | j                  z
  }|dk  s||kD  r|}| j                  j                  |      }| xj                  t	        |      z  c_        |S )Nr:   )rz   r   ry   r;   r?   )r)   countblrH   s       r-   r;   zDeltaApplyReader.read  sS    ZZ$(("19
E ##E*CIr/   rR   c                     |dk7  s|t        t        dd      k7  rt        d      d| _        | j                  j                  d       y)zhAllows to reset the stream to restart reading

        :raise ValueError: If offset and whence are not 0r   rR   rT   N)rU   rV   rW   r   ry   r[   rX   s      r-   r[   zDeltaApplyReader.seek  s@     Q;&GB
A$>>:;;Qr/   c                     t        |      dk  rt        d      |d   j                  t        v rt        d|d   j                  z         | |      S )a  
        Convert the given list of streams into a stream which resolves deltas
        when reading from it.

        :param stream_list: two or more stream objects, first stream is a Delta
            to the object that you want to resolve, followed by N additional delta
            streams. The list's last stream must be a non-delta stream.

        :return: Non-Delta OPackStream object whose stream can be used to obtain
            the decompressed resolved data
        :raise ValueError: if the stream list cannot be handled   zNeed at least two streamsrm   zNCannot resolve deltas if there is no base object stream, last one was type: %s)r?   rW   type_idr   type)clsr}   s     r-   rF   zDeltaApplyReader.new  sb     {a899 r?""k1`cnoqcrcwcwwy y ;r/   c                 .    | j                   j                  S r6   )rw   r   r7   s    r-   r   zDeltaApplyReader.type  s    }}!!!r/   c                 .    | j                   j                  S r6   )rw   r   r7   s    r-   r   zDeltaApplyReader.type_id  s    }}$$$r/   c                     | j                   S )z3:return: number of uncompressed bytes in the stream)rz   r7   s    r-   r,   zDeltaApplyReader.size  s     zzr/   Nr   )rn   ro   rp   rq   rr   k_max_memory_mover.   r   r   has_perf_modr4   r;   rU   rV   r[   rt   rF   propertyr   r   r,   ru   r/   r-   r   r   B  s    0I *  DH'V '3 #*"j!"<      4 " " % %  r/   r   c                   (    e Zd ZdZdZd Zd ZddZy)r   zpSimple stream writer which produces a sha whenever you like as it degests
    everything it is supposed to writesha1c                 "    t               | _        y r6   )r   r   r7   s    r-   r.   zSha1Writer.__init__2  s    J	r/   c                 N    | j                   j                  |       t        |      S )z{:raise IOError: If not all bytes could be written
        :param data: byte object
        :return: length of incoming data)r   updater?   r)   rH   s     r-   r   zSha1Writer.write7  s     
 			4yr/   c                 n    |r| j                   j                         S | j                   j                         S )z]:return: sha so far
        :param as_hex: if True, sha will be hex-encoded, binary otherwise)r   	hexdigestdigest)r)   as_hexs     r-   shazSha1Writer.shaD  s-     99&&((yy!!r/   Nrl   )rn   ro   rp   rq   rr   r.   r   r   ru   r/   r-   r   r   ,  s    *I
"r/   r   c                        e Zd ZdZdZd Zd Zy)r   zZWriter producing a sha1 while passing on the written bytes to the given
    write functionwriterc                 <    t         j                  |        || _        y r6   )r   r.   r   )r)   r   s     r-   r.   zFlexibleSha1Writer.__init__T  s    D!r/   c                 R    t         j                  | |       | j                  |       y r6   )r   r   r   r   s     r-   r   zFlexibleSha1Writer.writeX  s    t$Dr/   N)rn   ro   rp   rq   rr   r.   r   ru   r/   r-   r   r   N  s    Ir/   r   c                   L    e Zd ZdZdZd Zd Zd Zd Z e	e
dd      fd	Zd
 Zy)r   z=Remembers everything someone writes to it and generates a sha)r   r   c                     t         j                  |        t               | _        t	        j
                  t        j                        | _        y r6   )r   r.   r   r   r'   compressobjZ_BEST_SPEEDr   r7   s    r-   r.   zZippedStoreShaWriter.__init__b  s1    D!9##D$5$56r/   c                 .    t        | j                  |      S r6   )rU   r   r2   s     r-   __getattr__z ZippedStoreShaWriter.__getattr__g  s    txx&&r/   c                     t         j                  | |      }| j                  j                  | j                  j	                  |             |S r6   )r   r   r   r   compress)r)   rH   alens      r-   r   zZippedStoreShaWriter.writej  s8    d+txx((./r/   c                 j    | j                   j                  | j                  j                                y r6   )r   r   r   flushr7   s    r-   r   zZippedStoreShaWriter.closep  s    txx~~'(r/   rR   r   c                     |dk7  s|t        t        dd      k7  rt        d      | j                  j	                  d       y)z`Seeking currently only supports to rewind written data
        Multiple writes are not supportedr   rR   rT   N)rU   rV   rW   r   r[   rX   s      r-   r[   zZippedStoreShaWriter.seeks  s7     Q;&GB
A$>>:;;ar/   c                 6    | j                   j                         S )zA:return: string value from the current stream position to the end)r   getvaluer7   s    r-   r   zZippedStoreShaWriter.getvalue{  s    xx  ""r/   N)rn   ro   rp   rq   rr   r.   r   r   r   rU   rV   r[   r   ru   r/   r-   r   r   ]  s6    GI7
') #*"j!"< #r/   r   c                   B     e Zd ZdZdZ ed      Z fdZd Zd Z	 xZ
S )r   zDigests data written to it, making the sha available, then compress the
    data and write it to the file descriptor

    **Note:** operates on raw file descriptors
    **Note:** for this to work, you have to use the close-method of this instance)fdr   r   z+Failed to write all bytes to filedescriptorc                     t         |           || _        t        j                  t        j
                        | _        y r6   )superr.   r   r'   r   r   r   )r)   r   	__class__s     r-   r.   zFDCompressedSha1Writer.__init__  s-    ##D$5$56r/   c                     | j                   j                  |       | j                  j                  |      }t	        | j
                  |      }|t        |      k7  r| j                  t        |      S )zZ:raise IOError: If not all bytes could be written
        :return: length of incoming data)r   r   r   r   r   r   r?   exc)r)   rH   cdatabytes_writtens       r-   r   zFDCompressedSha1Writer.write  sY     			!!$'dggu-CJ&((N4yr/   c                     | j                   j                         }t        | j                  |      t	        |      k7  r| j
                  t        | j                        S r6   )r   r   r   r   r?   r   r   )r)   	remainders     r-   r   zFDCompressedSha1Writer.close  s@    HHNN$	)$I6((NTWW~r/   )rn   ro   rp   rq   rr   IOErrorr   r.   r   r   __classcell__)r   s   @r-   r   r     s,    U
 &I ?
@C7
r/   r   c                   :    e Zd ZdZdZd Zd Zd
dZd Zd Z	d Z
y	)r   zA simple wrapper providing the most basic functions on a file descriptor
    with the fileobject interface. Cannot use os.fdopen as the resulting stream
    takes ownership_fd_posc                      || _         d| _        y Nr   r   )r)   r   s     r-   r.   zFDStream.__init__  s    	r/   c                     | xj                   t        |      z  c_         t        j                  | j                  |       y r6   )r   r?   rV   r   r   r   s     r-   r   zFDStream.write  s&    		SY	
4 r/   c                     |dk(  r)t         j                  j                  | j                        }t        j                  | j
                  |      }| xj                  t        |      z  c_        |S r   )rV   pathgetsize	_filepathr;   r   r   r?   )r)   r   bytess      r-   r;   zFDStream.read  sL    A:GGOODNN3E %(		SZ	r/   c                     | j                   S r6   )r   r7   s    r-   filenozFDStream.fileno  s    xxr/   c                     | j                   S r6   )r   r7   s    r-   tellzFDStream.tell  s    yyr/   c                 .    t        | j                         y r6   )r   r   r7   s    r-   r   zFDStream.close  s    dhhr/   Nr   )rn   ro   rp   rq   rr   r.   r   r;   r   r   r   ru   r/   r-   r   r     s,      I!r/   r   c                   2    e Zd ZdZ e       ZddZd Zd Zy)r   zVA stream that does nothing but providing a stream interface.
    Use it like /dev/nullc                      y)N ru   )r)   r,   s     r-   r;   zNullStream.read  s    r/   c                      y r6   ru   r7   s    r-   r   zNullStream.close  s    r/   c                     t        |      S r6   )r?   r   s     r-   r   zNullStream.write  s    4yr/   Nr   )	rn   ro   rp   rq   r|   rr   r;   r   r   ru   r/   r-   r   r     s    Ir/   r   )%ior   rO   rV   rd   r'   	gitdb.funr   r   r   r   r   
gitdb.utilr	   r
   r   r   r   gitdb.constr   r   gitdb.utils.encodingr   r   gitdb_speedups._perfr   r   ImportError__all__r   r   r   r   r   r   r   r   ru   r/   r-   <module>r      s      	 
    . ,	AL%QY Qh`y `T" "D  #:  #F#Z #P D M  		s   B$ $B,+B,