
    Ii$                     \    S r SSKrSSKJr  SSKJr  SSKJrJrJ	r	  SSK
Jr   " S S5      rg)	z&
Implementation of an SSH2 "message".
    N)BytesIO)util)	zero_bytemax_byteone_byte)uc                       \ rS rSrSrSrS#S jrS rS rS r	S	 r
S
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S  r!S! r"S"r#g)$Message   ab  
An SSH2 message is a stream of bytes that encodes some combination of
strings, integers, bools, and infinite-precision integers.  This class
builds or breaks down such a byte stream.

Normally you don't need to deal with anything this low-level, but it's
exposed for people implementing custom extensions, or features that
paramiko doesn't support yet.
l      ~ Nc                 J    Ub  [        U5      U l        g[        5       U l        g)z
Create a new SSH2 message.

:param bytes content:
    the byte stream to use as the message content (passed in only when
    decomposing a message).
N)r   packet)selfcontents     6/venv/lib/python3.13/site-packages/paramiko/message.py__init__Message.__init__,   s     !'*DK!)DK    c                 "    U R                  5       $ N)asbytesr   s    r   	__bytes__Message.__bytes__9   s    ||~r   c                 T    S[        U R                  R                  5       5      -   S-   $ )z@
Returns a string representation of this object, for debugging.
zparamiko.Message())reprr   getvaluer   s    r   __repr__Message.__repr__<   s&     #T$++*>*>*@%AACGGr   c                 6    U R                   R                  5       $ )z?
Return the byte stream content of this Message, as a `bytes`.
)r   r   r   s    r   r   Message.asbytesC   s     {{##%%r   c                 :    U R                   R                  S5        g)zS
Rewind the message to the beginning as if no items had been parsed
out of it yet.
r   N)r   seekr   s    r   rewindMessage.rewindI   s    
 	r   c                     U R                   R                  5       nU R                   R                  5       nU R                   R                  U5        U$ )zS
Return the `bytes` of this message that haven't already been parsed and
returned.
)r   tellreadr#   )r   position	remainders      r   get_remainderMessage.get_remainderP   s@    
 ;;##%KK$$&	"r   c                     U R                   R                  5       nU R                  5         U R                   R                  U5      $ )z
Returns the `bytes` of this message that have been parsed and
returned. The string passed into a message's constructor can be
regenerated by concatenating ``get_so_far`` and `get_remainder`.
)r   r'   r$   r(   )r   r)   s     r   
get_so_farMessage.get_so_farZ   s4     ;;##%{{))r   c                     U R                   R                  U5      nSn[        U5      Us=:  a  U:  a  O  U$ U[        U[        U5      -
  -  -   $ U$ )z
Return the next ``n`` bytes of the message, without decomposing into an
int, decoded string, etc.  Just the raw bytes are returned. Returns a
string of ``n`` zero bytes if there weren't ``n`` bytes remaining in
the message.
i   )r   r(   lenr   )r   nbmax_pad_sizes       r   	get_bytesMessage.get_bytesd   sR     KKQq6A$$ yAAJ///r   c                 $    U R                  S5      $ )z
Return the next byte of the message, without decomposing it.  This
is equivalent to `get_bytes(1) <get_bytes>`.

:return:
    the next (`bytes`) byte of the message, or ``b' '`` if there
    aren't any bytes remaining.
   )r5   r   s    r   get_byteMessage.get_byteq   s     ~~a  r   c                 6    U R                  S5      nU[        :g  $ )z"
Fetch a boolean from the stream.
r8   )r5   r   r   r3   s     r   get_booleanMessage.get_boolean|   s     NN1I~r   c                     U R                  S5      nU[        :X  a$  [        R                  " U R	                  5       5      $ XR                  S5      -  n[
        R                  " SU5      S   $ )zB
Fetch an int from the stream.

:return: a 32-bit unsigned `int`.
r8      >Ir   )r5   r   r   inflate_long
get_binarystructunpack)r   bytes     r   get_adaptive_intMessage.get_adaptive_int   sY     ~~a 8$$T__%677q!!}}T4(++r   c                 T    [         R                  " SU R                  S5      5      S   $ )z
Fetch an int from the stream.
rA      r   rD   rE   r5   r   s    r   get_intMessage.get_int   s#     }}T4>>!#45a88r   c                 T    [         R                  " SU R                  S5      5      S   $ )zR
Fetch a 64-bit int from the stream.

:return: a 64-bit unsigned integer (`int`).
>Q   r   rK   r   s    r   	get_int64Message.get_int64   s#     }}T4>>!#45a88r   c                 J    [         R                  " U R                  5       5      $ )zZ
Fetch a long int (mpint) from the stream.

:return: an arbitrary-length integer (`int`).
)r   rB   rC   r   s    r   	get_mpintMessage.get_mpint   s       !233r   c                 @    U R                  U R                  5       5      $ )z
Fetch a "string" from the stream.  This will actually be a `bytes`
object, and may contain unprintable characters.  (It's not unheard of
for a string to contain another byte-stream message.)
r5   rL   r   s    r   
get_stringMessage.get_string   s     ~~dlln--r   c                 4    [        U R                  5       5      $ )zz
Fetch a Unicode string from the stream.

This currently operates by attempting to encode the next "string" as
``utf-8``.
)r   rX   r   s    r   get_textMessage.get_text   s     "##r   c                 @    U R                  U R                  5       5      $ )z0
Alias for `get_string` (obtains a bytestring).
rW   r   s    r   rC   Message.get_binary   s     ~~dlln--r   c                 @    U R                  5       R                  S5      $ )zv
Fetch a list of `strings <str>` from the stream.

These are trivially encoded as comma-separated values in a string.
,)r[   splitr   s    r   get_listMessage.get_list   s     }}$$S))r   c                 <    U R                   R                  U5        U $ )zR
Write bytes to the stream, without any formatting.

:param bytes b: bytes to add
r   writer<   s     r   	add_bytesMessage.add_bytes        	!r   c                 <    U R                   R                  U5        U $ )zY
Write a single byte to the stream, without any formatting.

:param bytes b: byte to add
re   r<   s     r   add_byteMessage.add_byte   ri   r   c                     U(       a!  U R                   R                  [        5        U $ U R                   R                  [        5        U $ )zI
Add a boolean value to the stream.

:param bool b: boolean value to add
)r   rf   r   r   r<   s     r   add_booleanMessage.add_boolean   s9     KKh'  KKi(r   c                 f    U R                   R                  [        R                  " SU5      5        U $ z=
Add an integer to the stream.

:param int n: integer to add
rA   r   rf   rD   packr   r2   s     r   add_intMessage.add_int   &     	&++dA./r   c                    U[         R                  :  aF  U R                  R                  [        5        U R                  [        R                  " U5      5        U $ U R                  R                  [        R                  " SU5      5        U $ rq   )
r
   big_intr   rf   r   
add_stringr   deflate_longrD   rs   rt   s     r   add_adaptive_intMessage.add_adaptive_int   sd     KKh'OOD--a01  KKfkk$23r   c                 f    U R                   R                  [        R                  " SU5      5        U $ )z@
Add a 64-bit int to the stream.

:param int n: long int to add
rO   rr   rt   s     r   	add_int64Message.add_int64   rw   r   c                 P    U R                  [        R                  " U5      5        U $ )z
Add a long int to the stream, encoded as an infinite-precision
integer.  This method only works on positive numbers.

:param int z: long int to add
)rz   r   r{   )r   zs     r   	add_mpintMessage.add_mpint  s      	))!,-r   c                     [         R                  " U5      nU R                  [        U5      5        U R                  R                  U5        U $ )zC
Add a bytestring to the stream.

:param byte s: bytestring to add
)r   r   ru   r1   r   rf   )r   ss     r   rz   Message.add_string  s8     LLOSV!r   c                 F    U R                  SR                  U5      5        U $ )z
Add a list of strings to the stream.  They are encoded identically to
a single string of values separated by commas.  (Yes, really, that's
how SSH2 does it.)

:param l: list of strings to add
r`   )rz   join)r   ls     r   add_listMessage.add_list  s     	$r   c                     [        U5      [        L a  U R                  U5      $ [        U[        5      (       a  U R                  U5      $ [        U5      [        L a  U R                  U5      $ U R                  U5      $ r   )	typeboolrn   
isinstanceintr|   listr   rz   )r   is     r   _addMessage._add'  se    7d?##A&&3((++!W_==##??1%%r   c                 8    U H  nU R                  U5        M     g)z
Add a sequence of items to the stream.  The values are encoded based
on their type: bytes, str, int, bool, or list.

.. warning::
    Longs are encoded non-deterministically.  Don't use this method.

:param seq: the sequence of items
N)r   )r   seqitems      r   addMessage.add3  s     DIIdO r   )r   r   )$__name__
__module____qualname____firstlineno____doc__ry   r   r   r   r   r$   r+   r.   r5   r9   r=   rG   rL   rQ   rT   rX   r[   rC   rb   rg   rk   rn   ru   r|   r   r   rz   r   r   r   __static_attributes__ r   r   r
   r
      s     G$H&*	!
,994.$.*
		&r   r
   )r   rD   ior   paramikor   paramiko.commonr   r   r   paramiko.utilr   r
   r   r   r   <module>r      s*   &    9 9 _ _r   