
    dG                        d Z ddlmZ ddlmZ ddlZddlmZmZ dZ	dZ
dZdZd	ZdZd	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%d Z&eee e"egZ' e(e'e!eeeee#eeee$e%gz             Z) e(e'eeeegz             Z*d!Z+d"Z,d# Z-d$ Z.d% Z/d& Z0d' Z1d( Z2d)Z3dZ4d*Z5d+Z6d,Z7d-Z8d. Z9d/ Z:d0 Z; G d1 d2          Z<d3Z= G d4 d5e<          Z>d6 Z?d7 Z@d8 ZA G d9 d:          ZB G d; d<          ZCd= ZDdCd>ZEd? ZFd@ ZGdDdBZHdS )Ez<Generic functions for talking the git smart server protocol.    )BytesIO)SEEK_ENDN   )GitProtocolErrorHangupExceptioni$  s(   0000000000000000000000000000000000000000      s   atomics   deepen-sinces
   deepen-nots   deepen-relatives   delete-refss   include-tag	   multi_ack   multi_ack_detaileds   no-dones   no-progresss	   ofs-deltas   quiets   report-statuss   shallows	   side-bands   side-band-64ks	   thin-packs   agents   symrefs   allow-tip-sha1-in-wants   allow-reachable-sha1-in-wants   capabilities^{}is   NAK
c                      dd                     t          t          t          j                            z                       d          S )Nzdulwich/.ascii)joinmapstrdulwich__version__encode     T/home/feoh/.local/pipx/venvs/poetry/lib/python3.11/site-packages/dulwich/protocol.pyagent_stringr   n   s4    #c7+>"?"?@@@HHQQQr   c                  4    t           dz   t                      z   S )N   =)CAPABILITY_AGENTr   r   r   r   capability_agentr   r   s    d"\^^33r   c                 (    t           dz   | z   dz   |z   S )Nr      :)CAPABILITY_SYMREF)from_refto_refs     r   capability_symrefr"   v   s    t#h.5>>r   c                     d | D             S )Nc                 8    h | ]}t          |          d          S )r   )parse_capability.0cs     r   	<setcomp>z+extract_capability_names.<locals>.<setcomp>{   s&    999qQ"999r   r   capabilitiess    r   extract_capability_namesr,   z   s    99L9999r   c                     |                      dd          }t          |          dk    r
|d         d fS t          |          S )Nr   r   r   )splitlentuple)
capabilitypartss     r   r%   r%   ~   sA    T1%%E
5zzQa$<<r   c                     d | D             S )Nc                      g | ]}t          | S r   )r"   )r'   ks     r   
<listcomp>z'symref_capabilities.<locals>.<listcomp>   s    333aq!333r   r   )symrefss    r   symref_capabilitiesr8      s    3373333r   s   deepens	   unshallows   dones   wants   havec                 L    | dz   d                     d |D                       z   S )N    r   c                     g | ]}|d z   S )    r   )r'   as     r   r6   z"format_cmd_pkt.<locals>.<listcomp>   s    !<!<!<!1u9!<!<!<r   r   )cmdargss     r   format_cmd_pktrA      s,    :!<!<t!<!<!<====r   c                     |                      d          }| d |         | |dz   d          }}|dd          dk    sJ ||d d                             d          fS )Nr:   r   r<   )findr.   )line	splice_atr?   r@   s       r   parse_cmd_pktrG      sh    		$IZiZ $y1}"7C9SbS	&&&&r   c                 `    | dS dt          |           dz   z                      d          | z   S )zWrap data in a pkt-line.

    Args:
      data: The data to wrap, as a str or None.
    Returns: The data prefixed with its length in pkt-line format; if data was
        None, returns the flush-pkt ('0000').
    Ns   0000z%04x   r   )r/   r   )datas    r   pkt_linerK      s6     |wc$ii!m$,,W55<<r   c                   \    e Zd ZdZddZd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zd ZdS )Protocola  Class for interacting with a remote git process over the wire.

    Parts of the git wire protocol use 'pkt-lines' to communicate. A pkt-line
    consists of the length of the line as a 4-byte hex string, followed by the
    payload data. The length includes the 4-byte header. The special line
    '0000' indicates the end of a section of input and is called a 'flush-pkt'.

    For details on the pkt-line format, see the cgit distribution:
        Documentation/technical/protocol-common.txt
    Nc                 L    || _         || _        || _        || _        d | _        d S N)readwrite_closereport_activity
_readahead)selfrP   rQ   closerS   s        r   __init__zProtocol.__init__   s*    	
.r   c                 @    | j         r|                                   d S d S rO   )rR   rU   s    r   rV   zProtocol.close   s'    ; 	KKMMMMM	 	r   c                     | S rO   r   rY   s    r   	__enter__zProtocol.__enter__   s    r   c                 .    |                                   d S rO   )rV   )rU   exc_typeexc_valexc_tbs       r   __exit__zProtocol.__exit__   s    

r   c                 L   | j         | j        }n| j         j        }d| _         	  |d          }|st                      t          |d          }|dk    r| j        r|                     dd           dS | j        r|                     |d            ||dz
            }t          |          dz   |k    r$t          dt          |          dz   |fz            |S # t          $ r}t                      |d}~wt          $ r"}t          t          |                    |d}~ww xY w)a   Reads a pkt-line from the remote git process.

        This method may read from the readahead buffer; see unread_pkt_line.

        Returns: The next string from the stream, without the length prefix, or
            None for a flush-pkt ('0000').
        NrI      r   rP   z9Length of pkt read %04x does not match length prefix %04x)
rT   rP   r   intrS   r/   r   ConnectionResetErrorOSErrorr   )rU   rP   sizestrsizepkt_contentsexcs         r   read_pkt_linezProtocol.read_pkt_line   sh    ?"9DD?'D"DO	 d1ggG (%'''w##Dqyy' 4((F333t# 3$$T62224q>>L <  1$,,&O<((1,d34     $ 	- 	- 	-!##, 	6 	6 	6"3s88,,#5	6s*   AC 4+C 
D#%C44D#DD#c                 ~    	 |                                  }n# t          $ r Y dS w xY w|                     |           dS )zTest whether the protocol stream has reached EOF.

        Note that this refers to the actual stream EOF and not just a
        flush-pkt.

        Returns: True if the stream is at EOF, False otherwise.
        TF)rj   r   unread_pkt_line)rU   	next_lines     r   eofzProtocol.eof   sU    	**,,II 	 	 	44	Y'''us    
%%c                 t    | j         t          d          t          t          |                    | _         dS )a=  Unread a single line of data into the readahead buffer.

        This method can be used to unread a single pkt-line into a fixed
        readahead buffer.

        Args:
          data: The data to unread, without the length prefix.
        Raises:
          ValueError: If more than one pkt-line is unread.
        Nz'Attempted to unread multiple pkt-lines.)rT   
ValueErrorr   rK   rU   rJ   s     r   rl   zProtocol.unread_pkt_line   s4     ?&FGGG!(4..11r   c              #   n   K   |                                  }|r|V  |                                  }|dS dS )zRead a sequence of pkt-lines from the remote git process.

        Returns: Yields each line of data up to but not including the next
            flush-pkt.
        N)rj   )rU   pkts     r   read_pkt_seqzProtocol.read_pkt_seq
  sY         "" 	'III$$&&C  	' 	' 	' 	' 	'r   c                    	 t          |          }|                     |           | j        r%|                     t          |          d           dS dS # t          $ r"}t          t          |                    |d}~ww xY w)zSends a pkt-line to the remote git process.

        Args:
          line: A string containing the data to send, without the length
            prefix.
        rQ   N)rK   rQ   rS   r/   re   r   r   )rU   rE   ri   s      r   write_pkt_linezProtocol.write_pkt_line  s    	6D>>DJJt# 9$$SYY888889 9 	6 	6 	6"3s88,,#5	6s   AA 
B A;;B c                     |rI|                      t          t          |g                    |dd         z              |dd         }|GdS dS )zWrite multiplexed data to the sideband.

        Args:
          channel: An int specifying the channel to write to.
          blob: A blob of data (as a string) to send on this channel.
        N  )rv   bytes	bytearray)rU   channelblobs      r   write_sidebandzProtocol.write_sideband$  sj      	 i	&:&: ; ;d6E6l JKKK<D  	  	  	  	  	 r   c                 F    |                      t          |g|R             dS )zSend a command and some arguments to a git server.

        Only used for the TCP git protocol (git://).

        Args:
          cmd: The remote service to access.
          args: List of arguments to send to remove service.
        N)rv   rA   )rU   r?   r@   s      r   send_cmdzProtocol.send_cmd2  s.     	N3666677777r   c                 H    |                                  }t          |          S )zRead a command and some arguments from the git client

        Only used for the TCP git protocol (git://).

        Returns: A tuple of (command, [list of arguments]).
        )rj   rG   )rU   rE   s     r   read_cmdzProtocol.read_cmd=  s#     !!##T"""r   )NN)__name__
__module____qualname____doc__rW   rV   r[   r`   rj   rn   rl   rt   rv   r}   r   r   r   r   r   rM   rM      s        	 	         $  $  $ L  2 2 2	' 	' 	'6 6 6     	8 	8 	8# # # # #r   rM   i    c                   6     e Zd ZdZddef fd	Zd Zd Z xZS )ReceivableProtocola  Variant of Protocol that allows reading up to a size without blocking.

    This class has a recv() method that behaves like socket.recv() in addition
    to a read() method.

    If you want to read n bytes from the wire and block until exactly n bytes
    (or EOF) are read, use read(n). If you want to read at most n bytes from
    the wire but don't care if you get less, use recv(n). Note that recv(n)
    will still block until at least one byte is read.
    Nc                     t                                          | j        |||           || _        t	                      | _        || _        d S )N)rV   rS   )superrW   rP   _recvr   _rbuf	_rbufsize)rU   recvrQ   rV   rS   rbufsize	__class__s         r   rW   zReceivableProtocol.__init__W  sP     	IuE? 	 	
 	
 	
 
YY
!r   c                 D   |dk    sJ | j         }|                                }|                    dt                     |                                |z
  }||k    r|                    |           |                    |          }t                      | _         | j                             |                                           | j                             d           |S t                      | _         	 ||z
  }|                     |          }|sngt          |          }||k    r|s|S ||k    r|                    |           ~n1||k    sJ d||fz              |                    |           ||z  }~|                    |           |                                S )Nr   Tz_recv(%d) returned %d bytes)	r   tellseekr   rP   r   rQ   r   r/   )	rU   rg   bufstartbuf_lenrvleftrJ   ns	            r   rP   zReceivableProtocol.reada  s    axxxx
 j

H((**u$d??HHUOOO$B DJJSXXZZ(((JOOAIYY
	'>D ::d##D D		ADyyy Dyy		$999;tQiG999IIdOOOqLG3	6 	xxzzr   c                    |dk    sJ | j         }|                                }|                    dt                     |                                }|                    |           ||z
  }|so|                     | j                  }t          |          |k    r|S t                      }|                    |           |                    d           ~|| _         |	                    |          S )Nr   )
r   r   r   r   r   r   r/   r   rQ   rP   )rU   rg   r   r   r   r   rJ   s          r   r   zReceivableProtocol.recv  s    axxxxj

H((** 
	::dn--D4yyD  ))CIIdOOOHHQKKKDJxx~~r   )	r   r   r   r   	_RBUFSIZErW   rP   r   __classcell__)r   s   @r   r   r   K  so        	 	 "&ti" " " " " "; ; ;z      r   r   c                     d| vr| g fS |                                                      d          \  } }| |                                                    d          fS )zExtract a capabilities list from a string, if present.

    Args:
      text: String to extract from
    Returns: Tuple with text with capabilities removed and list of capabilities
    r<   r:   )rstripr.   strip)textr+   s     r   extract_capabilitiesr     s]     DRx,,U33D,,$$&&,,T2233r   c                     |                                                      d          }t          |          dk     r| g fS d                    |dd                   |dd         fS )ax  Extract a capabilities list from a want line, if present.

    Note that want lines have capabilities separated from the rest of the line
    by a space instead of a null byte. Thus want lines have the form:

        want obj-id cap1 cap2 ...

    Args:
      text: Want line to extract from
    Returns: Tuple with text with capabilities removed and list of capabilities
    r:   r	   Nr   )r   r.   r/   r   )r   
split_texts     r   extract_want_line_capabilitiesr     s`     $$T**J
:RxIIj!n%%z!""~66r   c                 <    d| v rt           S d| v rt          S t          S )z.Extract the ack type from a capabilities list.r   r
   )MULTI_ACK_DETAILED	MULTI_ACK
SINGLE_ACKr*   s    r   ack_typer     s*    ,,!!		%	%r   c                   &    e Zd ZdZddZd Zd ZdS )BufferedPktLineWritera  Writer that wraps its data in pkt-lines and has an independent buffer.

    Consecutive calls to write() wrap the data in a pkt-line and then buffers
    it until enough lines have been written such that their total length
    (including length prefix) reach the buffer size.
    rx   c                 V    || _         || _        t                      | _        d| _        dS )zInitialize the BufferedPktLineWriter.

        Args:
          write: A write callback for the underlying writer.
          bufsize: The internal buffer size, including length prefixes.
        r   N)_write_bufsizer   _wbuf_buflen)rU   rQ   bufsizes      r   rW   zBufferedPktLineWriter.__init__  s(     YY
r   c                 p   t          |          }t          |          }| j        |z   | j        z
  }|dk    r<||z
  }| j                            |d|                    |                                  nd}||d         }| j                            |           | xj        t          |          z  c_        dS )z&Write data, wrapping it in a pkt-line.r   N)rK   r/   r   r   r   rQ   flush)rU   rJ   rE   line_lenoverr   saveds          r   rQ   zBufferedPktLineWriter.write  s    ~~t99|h&6199tOEJT&5&\***JJLLLLEUVV
E

"r   c                     | j                                         }|r|                     |           d| _        t	                      | _         dS )zFlush all data from the buffer.r   N)r   getvaluer   _lenr   rq   s     r   r   zBufferedPktLineWriter.flush  sE    z""$$ 	KK	YY


r   N)rx   )r   r   r   r   rW   rQ   r   r   r   r   r   r     sP         
 
 
 
# # #    r   r   c                   $    e Zd ZdZd Zd Zd ZdS )PktLineParserzBPacket line parser that hands completed packets off to a callback.c                 :    || _         t                      | _        d S rO   )
handle_pktr   rT   )rU   r   s     r   rW   zPktLineParser.__init__  s    $!))r   c                 0   | j                             |           | j                                         }t          |          dk     rdS t          |          dk    rt	          |dd         d          }|dk    r |                     d           |dd         }n<|t          |          k    r(|                     |d|                    ||d         }nnt          |          dk    t                      | _         | j                             |           dS )zAParse a fragment of data and call back for any completed packets.rI   Nrb   r   )rT   rQ   r   r/   rc   r   r   )rU   rJ   r   rg   s       r   parsezPktLineParser.parse  s   d###o&&((s88a<<F#hh!mms2A2w##Dqyy%%%!""gS!!AdF,,,$%%j #hh!mm "))c"""""r   c                 4    | j                                         S )zRead back any unused data.)rT   r   rY   s    r   get_tailzPktLineParser.get_tail$  s    '')))r   N)r   r   r   r   rW   r   r   r   r   r   r   r   
  sG        LL$ $ $# # #&* * * * *r   r   c                 @    d                     d | D                       S )Nr   c                     g | ]}d |z   S )r:   r   r&   s     r   r6   z*format_capability_line.<locals>.<listcomp>*  s    444!TAX444r   r>   r*   s    r   format_capability_liner   )  s#    8844|444555r   c                 X    ||dz   | z   dz   S |dz   | z   dz   t          |          z   dz   S )Nr:      
r<   )r   )refshar+   s      r   format_ref_liner   -  sL    TzC%'' $Ju$$\223	r   c                     t           dz   | z   S Nr:   )COMMAND_SHALLOWr   s    r   format_shallow_liner   7  s    T!C''r   c                     t           dz   | z   S r   )COMMAND_UNSHALLOWr   s    r   format_unshallow_liner   ;  s    t#c))r   r   c                 &    |rd|z   }d| z   |z   dz   S )Nr:   s   ACK r   r   )r   r   s     r   format_ack_liner   ?  s'     #(?S=8#e++r   rO   )r   )Ir   ior   osr   r   errorsr   r   TCP_GIT_PORTZERO_SHAr   r   r   SIDE_BAND_CHANNEL_DATASIDE_BAND_CHANNEL_PROGRESSSIDE_BAND_CHANNEL_FATALCAPABILITY_ATOMICCAPABILITY_DEEPEN_SINCECAPABILITY_DEEPEN_NOTCAPABILITY_DEEPEN_RELATIVECAPABILITY_DELETE_REFSCAPABILITY_INCLUDE_TAGCAPABILITY_MULTI_ACKCAPABILITY_MULTI_ACK_DETAILEDCAPABILITY_NO_DONECAPABILITY_NO_PROGRESSCAPABILITY_OFS_DELTACAPABILITY_QUIETCAPABILITY_REPORT_STATUSCAPABILITY_SHALLOWCAPABILITY_SIDE_BANDCAPABILITY_SIDE_BAND_64KCAPABILITY_THIN_PACKr   r   !CAPABILITY_ALLOW_TIP_SHA1_IN_WANT'CAPABILITY_ALLOW_REACHABLE_SHA1_IN_WANTCAPABILITIES_REFCOMMON_CAPABILITIESsetKNOWN_UPLOAD_CAPABILITIESKNOWN_RECEIVE_CAPABILITIESDEPTH_INFINITENAK_LINEr   r   r"   r,   r%   r8   COMMAND_DEEPENr   r   COMMAND_DONECOMMAND_WANTCOMMAND_HAVErA   rG   rK   rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s  , C B              5 5 5 5 5 5 5 5
	      ) % / ' ' #  5  ' #  +  # + #   $= !*I ' &     C%")/    !S 	   R R R4 4 4? ? ?: : :  4 4 4   > > >' ' '
= 
= 
=\# \# \# \# \# \# \# \#~ 	h h h h h h h hV
4 
4 
47 7 7$  ) ) ) ) ) ) ) )X* * * * * * * *>6 6 6   ( ( (* * *, , , , , ,r   