o `J @sddlmZddlmZmZmZddlZddlmZGddde Z GdddeZ e j e j d ZGd d d eZGd d d eZGdddeZddZGdddZGdddeZGdddeZeddeddeddeeddedded d!ed d"ed d#ed$ ZGd%d&d&Zeeed'eed'eed(d)Gd*d+d+ZGd,d-d-eZGd.d/d/ZGd0d1d1Zd2d3Zd4d5Zeeed(egZd6d7Z d8d9d9d9d'd9d9d:d'd; Z!dd?d?Z#Gd@dAdAZ$GdBdCdCZ%GdDdEdEZ&dS)F)deque)EnumIntEnumIntFlagN)Optionalc@seZdZdZdS)SizeLimitErrorzRaised when trying to (de-)serialise data exceeding D-Bus' size limit. This is currently only implemented for arrays, where the maximum size is 64 MiB. N)__name__ __module__ __qualname____doc__r r 3/usr/lib/python3/dist-packages/jeepney/low_level.pyrsrc@s$eZdZdZdZddZddZdS) EndiannesscC|tjurdSdS)N<>rlittleselfr r r struct_codezEndianness.struct_codecCr)NlBrrr r r dbus_coderzEndianness.dbus_codeN)rr r rbigrrr r r r rs  r)rrc@seZdZdZdZdZdZdS) MessageTyperrN)rr r method_call method_returnerrorsignalr r r r rs rc@seZdZdZdZdZdS) MessageFlagrrr N)rr r no_reply_expected no_auto_startallow_interactive_authorizationr r r r r%#sr%c@s0eZdZdZdZdZdZdZdZdZ dZ d Z d S) HeaderFieldsrrrr  N) rr r path interfacemember error_name reply_serial destinationsender signatureunix_fdsr r r r r))sr)cCs|||}||kr dS|SNrr )possteppadr r r padding5s r<c@s8eZdZddZd ddZdddZd d Zd d ZdS) FixedTypecCs||_|_||_dSN)size alignmentr)rr?rr r r __init__=s  zFixedType.__init__r cCsJ|t||j7}||j}t|||||jd}|||jfSr8)r<r@rstructunpackr?)rbufr9 endiannessfdscodevalr r r parse_dataAszFixedType.parse_dataNcCs.dt||j}||j}|t||S)N)r<r@rrBpack)rdatar9rErFr;rGr r r serialiseGszFixedType.serialisecCsd|j|jS)NzFixedType({!r}, {!r}))formatr?rrr r r __repr__LszFixedType.__repr__cCs$t|tuo|j|jko|j|jkSr>)typer=r?rrotherr r r __eq__Os zFixedType.__eq__r r>)rr r rArIrMrOrSr r r r r=<s    r=cs:eZdZfddZd fdd ZddZdd ZZS) BooleanctdddSNr IsuperrAr __class__r r rAUrzBoolean.__init__r cs t|||\}}t||fSr>)rZrIbool)rrDr9rErFrHnew_posr[r r rIX zBoolean.parse_datacCdS)Nz Boolean()r rr r r rO\zBoolean.__repr__cC t|tuSr>)rPrUrQr r r rS_ zBoolean.__eq__rT)rr r rArIrOrS __classcell__r r r[r rUTs  rUcsHeZdZfddZd fdd Zdfdd Zd d Zd d ZZS)FileDescriptorcrVrWrYrr[r r rAdrzFileDescriptor.__init__r cs t|||\}}|||fSr>)rZrI)rrDr9rErFidxr^r[r r rIgr_zFileDescriptor.parse_dataNcsx|durtdt|dr|}t|tst|tstd|dkr+td|d||t t |d||S)Nz+Sending FDs is not supported or not enabledfilenozYCannot use {data!r} as file descriptor. Expected an int or an object with fileno() methodrz#File descriptor can't be negative ()r) RuntimeErrorhasattrrg isinstancer]int TypeError ValueErrorappendrZrMlen)rrLr9rErFr[r r rMks  zFileDescriptor.serialisecCr`)NzFileDescriptor()r rr r r rO{razFileDescriptor.__repr__cCrbr>)rPrerQr r r rS~rczFileDescriptor.__eq__rTr>) rr r rArIrMrOrSrdr r r[r recs  rerBrhHr irXr-qQd) ynrubrtuxtrwrrc@sDeZdZddZeddZdddZdd d Zd d Zd dZ dS) StringTypecC ||_dSr>) length_type)rrr r r rA zStringType.__init__cCs|jjSr>)rr?rr r r r@szStringType.alignmentr cCsR|j|||\}}||}|||d}|||ddks#J||dfS)Nutf-8rrJ)rrIdecode)rrDr9rErFlengthendrHr r r rIs  zStringType.parse_dataNcCsBt|ts td||d}|jt|||}||dS)NzExpected str, not {!r}rrJ)rkstrrmrNencoderrMrp)rrLr9rErFencodedlen_datar r r rMs   zStringType.serialisecC d|jS)NzStringType({!r}))rNrrr r r rOrczStringType.__repr__cCt|tuo |j|jkSr>)rPr~rrQr r r rSs  zStringType.__eq__rTr>) rr r rApropertyr@rIrMrOrSr r r r r~s    r~r{rx)sogc@s<eZdZdZddZdddZddd Zd d Zd d ZdS)Structr-cCs$tdd|Dr td||_dS)Ncss|]}t|tVqdSr>)rk DictEntry).0fr r r sz"Struct.__init__..zFound dict entry outside array)anyrmfieldsrrr r r rAs zStruct.__init__r cCsJ|t|d7}g}|jD]}|j||||d\}}||q t||fS)Nr-rF)r<rrIrotuple)rrDr9rErFresfieldvr r r rIs    zStruct.parse_dataNc Cst|ts td|t|t|jkr"tdt|t|jdt||j}|t|7}g}t ||jD]\}}| |j ||||d|t|d7}q8|d |S)NzExpected tuple, not {!r}z{} entries for {} fieldsrJr) rkrrmrNrprrnr<r@ziprorMjoin) rrLr9rErFr; res_piecesitemrr r r rMs  zStruct.serialisecCsdt|j|jS)Nz{}({!r}))rNrPrrrr r r rOszStruct.__repr__cCst|t|uo |j|jkSr>)rPrrQr r r rSsz Struct.__eq__rTr>) rr r r@rArIrMrOrSr r r r rs   rcseZdZfddZZS)rcsTt|dkrtdt|t|dttfs"tdt|dt|dS)Nrz%Dict entry must have 2 fields, not %drz5First field in dict entry must be simple type, not {}) rprmrkr=r~rNrPrZrArr[r r rAs  zDictEntry.__init__)rr r rArdr r r[r rsrc@sFeZdZdZeddZddZdddZdd d Zd d Z d dZ dS)Arrayr rXcCrr>)elt_type)rrr r r rArzArray.__init__r c Cs|j|||\}}|t||jj7}||}|jtdkr&||||fSg}||krA|jj||||d\}}||||ks,t|jtrKt |}||fS)Nrxr) rrIr<rr@ simple_typesrorkrdict) rrDr9rErFrrrrr r r rIs  zArray.parse_dataNc CsDd}t|jtrt|tr|}n|jtdkr!t|tr!d}n t|ts-td |t|jt rA|jj t |dkrAt dt||j}||d}t||jj}|rY|} n1||} | d} g} |D]} | |jj| | ||d| t | d 7} | | krt dqed | } |jt | |||}d ||d || S) NFrxTzNot suitable for array: {!r}izArray size exceeds 64 MiB limitr rrrrJ)rkrrritemsrbyteslistrmrNr=r?rprr<r@rorMrr)rrLr9rErF data_is_bytespad1pos_after_lengthpad2rDdata_pos limit_poschunksrrr r r rMs:       zArray.serialisecCr)Nz Array({!r}))rNrrr r r rO%rczArray.__repr__cCrr>)rPrrrQr r r rS(z Array.__eq__rTr>) rr r r@r=rrArIrMrOrSr r r r rs   & rc@s4eZdZdZd ddZd ddZdd Zd d ZdS)Variantrr cCsDtd|||\}}tt|}|j||||d\}}||f|fSNrr)rrIparse_signaturer)rrDr9rErFsigvaltyperHr r r rI/s  zVariant.parse_dataNcCsD|\}}tt|}td|||}||j||t|||dSr)rrrrMrp)rrLr9rErFrrsig_bufr r r rM8s  zVariant.serialisecCr`)Nz Variant()r rr r r rO@razVariant.__repr__cCrbr>)rPrrQr r r rSCrczVariant.__eq__rTr>)rr r r@rIrMrOrSr r r r r,s    rcCs|d}|dkrtt|S|dkrtS|dkr8g}|ddkr/|t||ddks"|dt|S|dkrZg}|ddkrQ|t||ddksD|dt|S|dvrbtd t|S) z-Parse a symbolic signature into objects. rar(rh{}z)}zUnexpected end of struct) poprrrrorrrnr)rtokenrder r r rFs,      rcCsttd|dd\}t|}t|d|dd\}t|d|dd\}d|}|t|d|S)NcrrXr r- )rBrC endian_maprr<)rDendian body_lengthfields_array_len header_lenr r r calc_msg_sizeas rcCs$t|d|\}}dd|D|fS)NrcSsi|] \}}t||dqS)r)r))rkrr r r osz'parse_header_fields..)_header_fields_typerI)rDrElr9r r r parse_header_fieldsmsrrrr) rrrr r*r+r,r-r.cCs$ddt|D}t|d|S)NcSs"g|] \}}|jt||ffqSr )valueheader_field_codes)rrtrr r r s"z+serialise_header_fields..r)sortedrrrM)rwrErr r r serialise_header_fieldssrc@s2eZdZddZddZd ddZedd ZdS) HeadercCs6||_t||_t||_||_||_||_||_dS)zA D-Bus message header It's not normally necessary to construct this directly: use higher level functions and methods instead. N) rEr message_typer%flagsprotocol_versionrserialr)rrErrrrrrr r r rAs   zHeader.__init__c Cs$d|j|j|j|j|j|j|jS)Nz7Header({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, fields={!r}))rNrErrrrrrrr r r rOs zHeader.__repr__Nc CsP|jd}|dur|j}t||j|jj|j|j |j |t |j |jS)NcBBBII) rErrrBrKrrrrrrrr)rrrr r r rMs  zHeader.serialisec Csjtd|dd\}}}}t|}t|d|dd\}}t||\}} ||||||||| fS)NcBBBr IIr)rBrCrrr) clsrDrmsgtyperpvbodylenrrr9r r r from_buffers  zHeader.from_bufferr>)rr r rArOrM classmethodrr r r r rs   rc@sHeZdZdZddZddZeddeddfd d Zddefd d Z d S)MessagezObject representing a DBus message. It's not normally necessary to construct this directly: use higher level functions and methods instead. cCs||_||_dSr>)headerbody)rrrr r r rAs zMessage.__init__cCsdt|j|j|jS)Nz{}({!r}, {!r}))rNrPrrrrr r r rOrzMessage.__repr__r rDreturnc Cst|\}}|jtjd}|t|kr"td|dt|d|d|}d}tj|jvrJ|jtj}t t d|}|j |||j |dd}t ||S)NrzMessage expects z FDs, but only z were receivedr (%s)r)rrrgetr)r7rprnr6rrrIrEr) rrDrFrr9n_fdsrr body_typer r r rs     zMessage.from_bufferNc Cs|jj}tj|jjvr%|jjtj}ttd|}|j|jd||d}nd}t ||j_ |r8t ||jjtj <|jj|d}dt t |d}|||S)aConvert this message to bytes. Specifying *serial* overrides the ``msg.header.serial`` field, so a connection can use its own serial number without modifying the message. If file-descriptor support is in use, *fds* should be a :class:`array.array` object with type ``'i'``. Any file descriptors in the message will be added to the array. If the message contains FDs, it can't be serialised without this array. rrrr)rrJr-) rrEr)r6rrrrMrrprr7r<) rrrFrrrbody_buf header_bufr;r r r rMs   zMessage.serialiserT)NN) rr r r rArOrrrrMr r r r rsrc@sJeZdZdZddZddefddZdd Zd d Zd e e fd dZ dS)Parserz8Parse DBus messages from a stream of incoming data. cCst|_g|_d|_dSr>) BufferPiperDrF next_msg_sizerr r r rAs zParser.__init__r rLcCs|j||j|dS)z)Provide newly received data to the parserN)rDwriterFextend)rrLrFr r r add_datas zParser.add_datacCs||tt|jdS)zhFeed the parser newly read data. Returns a list of messages completed by the new data. N)rriterget_next_message)rrLr r r feeds z Parser.feedcCs>|jj}|dkr d|S|jdurt|jd|_|j|S)zHow many bytes can be received without going beyond the next message? This is only used with file-descriptor passing, so we don't get too many FDs in a single recvmsg call. rN)rDbytes_bufferedrrpeek)rgotr r r bytes_desireds   zParser.bytes_desiredrcCs|jdur|jjdkrt|jd|_|j}|durE|jj|krG|j|}tj||jd}d|_|j j t j d}|j|d|_|SdSdS)zqParse one message, if there is enough data. Returns None if it doesn't have a complete message. Nrrr)rrDrrrreadrrrFrrrr)r7)rnmsraw_msgmsg fds_consumedr r r r s   zParser.get_next_messageNrT) rr r r rArrrrrrrr r r r rsrc@sfeZdZdZddZdefddZdefdd Zded efd d Z defd dZ ded efddZ dS)rzA place to store received data until we can parse a complete message The main difference from io.BytesIO is that read & write operate at opposite ends, like a pipe. cCst|_d|_dSr8)rrrrr r r rA!s zBufferPipe.__init__rzcCs"|j||jt|7_dSr>)rrorrp)rrzr r r r%s zBufferPipe.writenbytesccsL||jksJ|jD]}|d|}|t|8}|V|dkr#dSq dSr8)rrrp)rrchunkr r r _peek_iter)s   zBufferPipe._peek_iterrcCd||S)z=Get exactly nbytes bytes from the front without removing themr)rrrrr r r r2zBufferPipe.peekccs||jksJ |j}|jt|8_|t|krn |t|8}|Vq |d|||d}}|rF|j||jt|7_|VdSr>)rrpopleftrp appendleft)rrrremr r r _read_iter6s      zBufferPipe._read_itercCr)z1Take & return exactly nbytes bytes from the frontr)rrrr r r rGrzBufferPipe.readN) rr r r rArrrlrrrrr r r r rs r)' collectionsrenumrrrrBtypingrrnrrrrrrr%r)r<r=rUrerr~updaterrrrrrrrrrrrrrr r r r sl        & F  (:5