3 jf @sFdZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z dd l Z dd l Z dd l Z dd l Z dd lmZmZdd lmZd d ddddddgZe je jdjddZdd ZGdddeZeZdeed<dd ZddZddZddZ d dZ!eed!Z"d"dZ#ee d!Z$ee!d!Z%d&d%dZ&d S)'z Routines for manipulating RFC2047 encoded words. This is currently a package-private API, but will be considered for promotion to a public API if there is demand. )unicode_literals)division)absolute_import)bytes)chr)int)strN) ascii_lettersdigits)errorsdecode_qencode_qdecode_bencode_blen_qlen_bdecodeencodes=([a-fA-F0-9]{2})cCstt|jddgS)N)rrgroup)mrG/tmp/pip-build-s1i5078x/future/future/backports/email/_encoded_words.pyHsrcCst|jdd}t|gfS)N_ )rreplace_q_byte_subber)encodedrrrr Jsc@s0eZdZedejdejdZddZdS) _QByteMaps-!*+/asciicCs.||jkrt|||<ndj|||<||S)Nz={:02X})saferformat)selfkeyrrr __missing__Ts z_QByteMap.__missing__N) __name__ __module__ __qualname__rr rr r"r&rrrrr Psr _ cCstdjddt|DS)Ncss|]}t|VqdS)N) _q_byte_map).0xrrr aszencode_q..)rjoinr)bstringrrrr `scCstddt|DS)Ncss|]}tt|VqdS)N)lenr-)r.r/rrrr0dszlen_q..)sumr)r2rrrrcscCsg}t|d}|r8|jtj|ddd|}n|}y$tjd|sTtjdtj ||fStjk rtj g}x\d D]L}ytj |d ||fStjt fk r|dkr|jtjYqXqWt d YnXdS) Ns===s^[A-Za-z0-9+/]*={0,2}$zNon-base64 digit foundrr=zunexpected binascii.Error)rrr6r7) r3appendr InvalidBase64PaddingDefectrematchbinasciiErrorbase64 b64decodeInvalidBase64CharactersDefect TypeErrorAssertionError)rdefectspad_errZpadded_encodedirrrrks&     cCstj|jdS)Nr!)r? b64encoder)r2rrrrscCs&tt|d\}}|d|r dndS)Nr7r5r)divmodr3)r2 groups_of_3leftoverrrrrs)qbc Cst|jd\}}}}}|jd\}}}|j}|jdd}t||\}}y|j|}Wnvtk r|jt j dj ||j|d}YnBt k r|jdd}|jdkr|jt j dj |YnX||||fS)uDecode encoded word and return (string, charset, lang, defects) tuple. An RFC 2047/2243 encoded word has the form: =?charset*lang?cte?encoded_string?= where '*lang' may be omitted but the other parts may not be. This function expects exactly such a string (that is, it does not check the syntax and may raise errors if the string is not well formed), and returns the encoded_string decoded first from its Content Transfer Encoding and then from the resulting bytes into unicode using the specified charset. If the cte-decoded string does not successfully decode using the specified character set, a defect is added to the defects list and the unknown octets are replaced by the unicode 'unknown' character ﷿. The specified charset and language are returned. The default for language, which is rarely if ever encountered, is the empty string. ?*r!surrogateescapez:Encoded word contains bytes not decodable using {} charsetz unknown-8bitzsP       $    +